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

View File

@ -0,0 +1,315 @@
************************************************************************************************************
* 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

View File

@ -0,0 +1,336 @@
*! Raschfit version 3.1 (29 January 2006)
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : Raschfit
* The Raschfit and the Raschfit-fast procedures to construct sub-scales of items
* Release 3.1 : January 29, 2006 /*MEAN option in raschtestv7, correction of a bug when there is several scales*/
*
* 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]
*
* 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-2006 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'
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)
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
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)
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)
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

View File

@ -0,0 +1,217 @@
*! version 1.2 November 1st, 2010
*! Jean-Benoit Hardouin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : November 1st, 2010 (Jean-Benoit Hardouin)
*
* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010 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 raschpower,rclass
syntax [varlist] [, n0(int 100) n1(int 100) gamma(real .5) d(string) var(real 1) nodes(int 12)]
version 11
if "`d'"=="" {
tempname d
matrix `d'=[-1\-.5\0\.5\1]
}
/*tempname abs weight
ghquadm `nodes' `abs' `weight'
matrix `abs'=`abs''
matrix `weight'=`weight''
matrix `abs'=`abs'*sqrt(`var')
*matrix list `abs'
matrix `abs'=[5.50090170446774,4.27182584793228,3.22370982877010,2.25946445100080,1.34037519715162,0.444403001944139,-5.50090170446774,-4.27182584793228,-3.22370982877010,-2.25946445100080,-1.34037519715162,-0.444403001944139]
matrix `abs'=`abs''*sqrt(`var')
matrix `weight'=[0.000000375975985,0.000121250244966,0.005523056331147,0.072984713184739,0.368391758069477,0.806292983509187,0.000000375975985,0.000121250244966,0.005523056331147,0.072984713184739,0.368391758069477,0.806292983509187]
matrix `weight'=`weight''
*matrix list `abs'
*/
local nbitems=rowsof(`d')
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait: " in ye `var'
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: " _c
tempname dd
matrix `dd'=`d''
matrix list `dd',noblank nohalf nonames noheader
matrix `dd'=`d'/sqrt(`var')
local gamma=`gamma'/sqrt(`var')
clear
local temp=2^(`nbitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=1
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui g item`i'=mod(t,2^`i')==2^`=`i'-1'
qui replace t=t-item`i'*2^`=`i'-1'
qui count if t>0
loc z=r(N)
loc i=`i'+1
}
drop t
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
qui gen mean=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen proba=1
forvalues i=1/`nbitems' {
qui gen eps`i'=exp(mean-`d'[`i',1])
qui replace proba=proba*eps`i'^item`i'/(1+eps`i')
}
*list item* proba
qui gen eff=.
forvalues i=0/1 {
qui replace eff=proba*`n`i'' if group==`i'
}
/*
forvalues i=1/`nbitems' {
qui gen f`i'=eps`i'^item`i'/(1+eps`i')
qui gen fp`i'=(item`i'*eps`i'^item`i'+(item`i'-1)*eps`i'^(item`i'+1))/(1+eps`i')^2
qui gen fpp`i'=((item`i'^2*eps`i'^item`i'+(item`i'^2-1)*eps`i'^(item`i'+1))*(1+eps`i')^2-2*eps`i'*(1+eps`i')*(item`i'*eps`i'^item`i'+(item`i'-1)*eps`i'^(item`i'+1)))/(1+eps`i')^4
}
*/
qui replace eff=proba
keep item* eff group proba
local p1=1/`n1'
local p0=1/`n0'
qui gen eff2=.
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
*di "Nombre de patients affectes : `aff1' dans groupe 1 (sur `n1') et `aff0' dans le groupe 0 (sur `n0')"
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
*di "Nombre de patients non affectes : `unaff1' dans groupe 1 (sur `n1') et `unaff0' dans le groupe 0 (sur `n0')"
di "avant sort"
list item* group proba eff2
qui gsort + group - eff
list item* group proba eff2
qui replace eff2=eff2+1 in 1/`unaff0'
di "apres sort"
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
list item* group proba eff2
su proba
return list
*list eff eff2 group proba
qui drop if eff2==0
qui expand eff2
qui gen i=_n
tempname diff
matrix `diff'=`dd''
/***************************A REVOIR
forvalues i=1/`nbitems' {
qui su item`i'
local var=r(Var)
if `var'==0 {
qui drop item`i'
}
}
****************************FIN A REVOIR*/
*irtpoly item*, fixedvar(1) rasch fixed(`diff') covariablemean(group) sasout
qui drop proba eff eff2
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
}
constraint 1 _cons=0
qui gen groupc=group-.5
qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]*sqrt(`var')
local se=`V'[1,1]^.5*sqrt(`var')
di
di
di in gr "{hline 76}"
di _col(50) "Estimation with the "
di _col(40) "Cramer-Rao bound" _col(60) "classical formula"
di in gr "{hline 76}"
di in green "Estimated value of the group effect" _col(49) in ye %7.2f `gammaest'
di in green "Standard Error of this estimation" _col(49) in ye %7.2f `se'
di in green "Variance of this estimation" _col(46) in ye %10.4f `=`se'^2'
local power=1-normal(1.96-`gamma'*sqrt(`var')/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/(`n1'/`n0'+1))-1.96)
di in green "Estimated value of the power" _col(50) in ye %6.4f `power' _col(71) in ye %6.4f `clpower'
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*`gamma'^2)*(1.96-invnorm(1-`power'))^2
di in green "Number of patients for a power of" %6.2f `=`power'*100' "%" _col(49) in ye `n0' "/" `n1' _col(62) in ye %7.2f `clnsn' "/" %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(55)`=(`n0'+`n1')/(2*`clnsn')'
di in gr "{hline 76}"
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`power'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`=`n0'/`clnsn''
end

View File

@ -0,0 +1,220 @@
*! version 1.5 : July 11th, 2011
*! Jean-Benoit Hardouin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
*
* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2011 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower,rclass
syntax [varlist] [, n0(int 100) n1(int 100) gamma(real .5) d(string) var(real 1) fast nodata gammafix EXPectedpower(real -1)]
version 11
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
if "`d'"=="" {
tempname d
matrix `d'=[-1\-.5\0\.5\1]
}
local nbitems=rowsof(`d')
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait: " in ye `var'
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: " _c
tempname dd
matrix `dd'=`d''
matrix list `dd',noblank nohalf nonames noheader
matrix `dd'=`d'/*sqrt(`var')*/
local gamma=`gamma'/*sqrt(`var')*/
if "`data'"=="" {
clear
local temp=2^(`nbitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=1
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui g item`i'=mod(t,2^`i')==2^`=`i'-1'
qui replace t=t-item`i'*2^`=`i'-1'
qui count if t>0
loc z=r(N)
loc i=`i'+1
}
drop t
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
qui gen mean=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean=`n0'*`gamma'/(`n0'+`n1') if group==1
if "`fast'"=="" {
qui gen proba=.
forvalues i=1/`=2*`temp'' {
local int=1
forvalues j=1/`nbitems' {
qui su item`j' in `i'
local rep=r(mean)
local diff=`d'[`j',1]
local int "`int'*exp(`rep'*(x-`diff'))/(1+exp(x-`diff'))"
}
qui su mean in `i'
local mean=r(mean)
qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display
qui replace proba=r(int) in `i'
}
}
else {
qui gen proba=1
forvalues i=1/`nbitems' {
qui gen eps`i'=exp(mean-`d'[`i',1])
qui replace proba=proba*eps`i'^item`i'/(1+eps`i')
}
}
qui gen eff=.
forvalues i=0/1 {
qui replace eff=proba*`n`i'' if group==`i'
}
qui replace eff=proba
keep item* eff group proba
local p1=1/`n1'
local p0=1/`n0'
qui gen eff2=.
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
*qui drop if eff2==0
gsort group item*
gen res=proba*50
*list item* group efftmp eff2 proba
qui expand eff2
qui drop proba eff eff2
}
qui gen i=_n
*su
qui alpha item*
local alpha=r(alpha)
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
}
qui gen groupc=group-.5
matrix est=(`gamma',`=sqrt(`var')')
if "`gammafix'"=="" {
constraint 1 _cons=`=ln(`var')'
qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
}
else {
qui gllamm rep groupc, nocons i(i) offset(offset) iterate(0) fam(bin) link(logit) from(est) copy
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]/*sqrt(`var')*/
local se=`V'[1,1]^.5/*sqrt(`var')*/
di
di
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
local power=1-normal(1.96-`gamma'/*sqrt(`var')*//`se')+normal(-1.96-`gamma'*sqrt(`var')/`se')
local poweruni=1-normal(1.96-`gamma'/*sqrt(`var')*//`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/(`n1'/`n0'+1))-1.96)
/*si on ne n<>glige pas le deuxi<78>me terme, la bonne puissance est*/
*di in green "Estimation of the power" _col(60) in ye %6.4f `power' _col(86) in ye %6.4f `clpower'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
/*si on ne n<>glige pas le deuci<63>me terme, la bonne puissance est*/
*local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96-invnorm(1-`power'))^2
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96-invnorm(1-`poweruni'))^2
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`=(`n0'+`n1')/(2*`clnsn')'
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower')
local expn=r(N_1)
local expn2=`expn'*`=(`n0'+`n1')/(2*`clnsn')'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `expn2' _col(77) in ye %7.2f `expn' "/" %7.2f `expn'
}
di in gr "{hline 91}"
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`=`n0'/`clnsn''
return scalar CronbachAlpha=`alpha'
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,193 @@
*! version 1 january 25th, 2010
*! Jean-Benoit Hardouin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
*
* Jean-benoit Hardouin, Faculty of Pharmaceutical Sciences - University of Nantes - France
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010 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 raschpower1,rclass
syntax [varlist] [, n0(int 100) n1(int 100) gamma(real .5) d(string) var(real 1) nodes(int 12)]
if "`d'"=="" {
tempname d
matrix `d'=[-1\-.5\0\.5\1]
}
/*tempname abs weight
ghquadm `nodes' `abs' `weight'
matrix `abs'=`abs''
matrix `weight'=`weight''
matrix `abs'=`abs'*sqrt(`var')
*matrix list `abs'
matrix `abs'=[5.50090170446774,4.27182584793228,3.22370982877010,2.25946445100080,1.34037519715162,0.444403001944139,-5.50090170446774,-4.27182584793228,-3.22370982877010,-2.25946445100080,-1.34037519715162,-0.444403001944139]
matrix `abs'=`abs''*sqrt(`var')
matrix `weight'=[0.000000375975985,0.000121250244966,0.005523056331147,0.072984713184739,0.368391758069477,0.806292983509187,0.000000375975985,0.000121250244966,0.005523056331147,0.072984713184739,0.368391758069477,0.806292983509187]
matrix `weight'=`weight''
*matrix list `abs'
*/
local nbitems=rowsof(`d')
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait: " in ye `var'
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: " _c
tempname dd
matrix `dd'=`d''
matrix list `dd',noblank nohalf nonames noheader
clear
local temp=2^(`nbitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=1
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui g item`i'=mod(t,2^`i')==2^`=`i'-1'
qui replace t=t-item`i'*2^`=`i'-1'
qui count if t>0
loc z=r(N)
loc i=`i'+1
}
drop t
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
qui gen mean=(-1)^(1-group)*`gamma'*sqrt(`var')/2
qui gen proba=1
forvalues i=1/`nbitems' {
qui gen eps`i'=exp(mean-`d'[`i',1])
qui replace proba=proba*eps`i'^item`i'/(1+eps`i')
}
qui gen eff=.
forvalues i=0/1 {
qui replace eff=proba*`n`i'' if group==`i'
}
forvalues i=1/`nbitems' {
qui gen f`i'=eps`i'^item`i'/(1+eps`i')
qui gen fp`i'=(item`i'*eps`i'^item`i'+(item`i'-1)*eps`i'^(item`i'+1))/(1+eps`i')^2
qui gen fpp`i'=((item`i'^2*eps`i'^item`i'+(item`i'^2-1)*eps`i'^(item`i'+1))*(1+eps`i')^2-2*eps`i'*(1+eps`i')*(item`i'*eps`i'^item`i'+(item`i'-1)*eps`i'^(item`i'+1)))/(1+eps`i')^4
}
qui replace eff=proba
keep item* eff group proba
local p1=1/`n1'
local p0=1/`n0'
qui gen eff2=.
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
*di "Nombre de patients affectes : `aff1' dans groupe 1 (sur `n1') et `aff0' dans le groupe 0 (sur `n0')"
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
*di "Nombre de patients non affectes : `unaff1' dans groupe 1 (sur `n1') et `unaff0' dans le groupe 0 (sur `n0')"
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
*list eff eff2 group proba
qui drop if eff2==0
qui expand eff2
qui gen i=_n
tempname diff
matrix `diff'=`d''
/***************************A REVOIR
forvalues i=1/`nbitems' {
qui su item`i'
local var=r(Var)
if `var'==0 {
qui drop item`i'
}
}
****************************FIN A REVOIR*/
*irtpoly item*, fixedvar(1) rasch fixed(`diff') covariablemean(group) sasout
qui drop proba eff eff2
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
}
constraint 1 _cons=0
qui gen groupc=group-.5
xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
di
di
di in gr "{hline 76}"
di _col(50) "Estimation with the "
di _col(40) "Cramer-Rao bound" _col(60) "classical formula"
di in gr "{hline 76}"
di in green "Estimated value of the group effect" _col(49) in ye %7.2f `gammaest'
di in green "Standard Error of this estimation" _col(49) in ye %7.2f `se'
di in green "Variance if this estimation" _col(46) in ye %10.4f `=`se'^2'
local power=1-normal(1.96-`gamma'/`se')
local clpower=normal(sqrt(`n0'*`gamma'^2/2)-1.96)
di in green "Estimated value of the power" _col(50) in ye %6.4f `power' _col(71) in ye %6.4f `clpower'
local clnsn=2/`gamma'^2*(1.96-invnorm(1-`power'))^2
di in green "Number of patients for a power of" %6.2f `=`power'*100' "%" _col(49) in ye `n0' "/" `n1' _col(62) in ye %7.2f `clnsn' "/" %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(55)`=(`n0'+`n1')/(2*`clnsn')'
di in gr "{hline 76}"
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`power'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`=`n0'/`clnsn''
end

View File

@ -0,0 +1,374 @@
*! version 3.1 : October 25th, 2011
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2011 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpowerpcm,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(real 1) Method(string) NBPatterns(int 2) nodata gammafix EXPectedpower(real -1)]
version 11
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d
if "`difficulties'"=="" {
*matrix `d'=[-1\-.5\0\.5\1]
matrix `d'=[-1.151, -0.987\-0.615, -0.325\-0.184, -0.043\0.246, 0.554\0.782, 1.724]
*matrix `d'=[ -1.527, -1.019\-1.100, -0.793\-0.796, -0.369\-0.540, 0.152\-0.306, -0.220\-0.077, 0.147\0.156, 0.431\0.412, 0.685\0.716, 1.332\1.043, 1.572]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`=`nbmodat'^`nbitems'*2' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if "`method'"=="" {
if `nbmodat'^`nbitems'*2<1000 {
local method GH
}
else if `nbmodat'^`nbitems'<10000 {
local method MEAN+GH
}
else if `nbmodat'^`nbitems'<1000000 {
local method MEAN
}
else {
local method POPULATION+GH
}
}
di in gr "Method: " in ye "`method'"
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait: " in ye `var'
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
matrix list `dd',noblank nohalf noheader
di in gr "Number of studied response's patterns: " in ye `=`nbmodat'^`nbitems'*2'
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"&"`method'"!="POPULATION+MEAN" {
local temp=`nbmodat'^(`nbitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
else {
qui simirt, clear pcm(`difficulties') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui drop lt1
qui contract item* group, freq(freq)
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui keep if keep==1
qui count
local tmp=r(N)
di "Number of kept patterns:`tmp'"
local method GH
}
qui gen mean=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean=`n0'*`gamma'/(`n0'+`n1') if group==1
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
local int=1
forvalues j=1/`nbitems' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`d'[`j',1]
local sum "1+exp(x-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`d'[`j',`m']
local sum "`sum'+exp(`m'*x-`diff`m'')"
}
local int "(`int'*exp(`rep'*x-`diff`rep''))/(`sum')"
}
qui su mean in `i'
local mean=r(mean)
qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display
qui replace proba=r(int) in `i'
}
di
}
else {
qui gen proba=1
forvalues i=1/`nbitems' {
local diff0=0
local diff1=`d'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`d'[`i',`m']
qui gen eps`m'=exp(`m'*mean-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
local int=1
forvalues j=1/`nbitems' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`d'[`j',1]
local sum "1+exp(x-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`d'[`j',`m']
local sum "`sum'+exp(`m'*x-`diff`m'')"
}
local int "(`int'*exp(`rep'*x-`diff`rep''))/(`sum')"
}
qui su mean in `i'
local mean=r(mean)
qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display
qui replace proba=r(int) in `i'
}
}
}
qui gen eff=.
forvalues i=0/1 {
qui replace eff=proba*`n`i'' if group==`i'
}
qui replace eff=proba
qui keep item* eff group proba
local p1=1/`n1'
local p0=1/`n0'
qui gen eff2=.
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
qui gen groupc=group-.5
if `nbmodat'==1 {
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
}
matrix est=(`gamma',`=sqrt(`var')')
if "`gammafix'"=="" {
constraint 1 _cons=`=ln(`var')'
qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
}
else {
qui gllamm rep groupc, nocons i(i) offset(offset) iterate(0) fam(bin) link(logit) from(est) copy
}
tempname b V
}
else {
matrix `db'=`db''
qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var')
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
di
di
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local poweruni=1-normal(1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
di in gr "{hline 91}"
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,51 @@
{smcl}
{* 7july2011}{...}
{hline}
help for {hi:raschpower}{right:Jean-Benoit Hardouin, Myriam Blanchin}
{hline}
{title:Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals}
{p 8 14 2}{cmd:raschpower} [{cmd:,} {cmdab:n0}({it:#}) {cmdab:n1}({it:#})
{cmdab:gamma}({it:#}) {cmdab:var}({it:#}) {cmdab:d}({it:vector})]
{title:Description}
{p 4 8 2}{cmd:raschpower} allows estimating the power of the Wald test comparing the means of two groups of patients in the context of the Rasch model. The estimation is based on the estimation of the variance of the difference of the means based on the Cramer-Rao bound.
{title:Options}
{p 4 8 2}{cmd:n0} and {cmd:n1} indicates the numbers of individuals in the two groups (100 by default).
{p 4 8 2}{cmd:gamma} indicates the group effect (difference between the two means) [0.5 by default].
{p 4 8 2}{cmd:var} indicates the value of the variance of the latent trait [1 by default].
{p 4 8 2}{cmd:d} is a vector containing the difficulties of the items [one row per item, one column - (-1,-0.5,0,0.5,1)' by default].
{title:Example}
{p 4 8 2}{cmd:. raschpower}
{p 4 8 2}{cmd:. raschpower, n0(200) n1(200) gamma(0.4) var(1.3)}
{p 4 8 2}{cmd:. matrix diff=(-1.47\-0.97\-.23\-0.12\0.02\0.1)}{p_end}
{p 4 8 2}{cmd:. raschpower, n0(127) n1(134) gamma(0.23) d(diff) var(2.58)}{p_end}
{title:References}
{p 4 8 2}Hardouin J.B., Amri S., Feddag M., S<>bille V. (2011) Towards Power And Sample Size Calculations For The Comparison Of Two Groups Of Patients With Item Response Theory Models. Accept to appear in Statistics in Medicine.
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
{p 4 8 2}EA4275 "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,200 @@
*! version 8 25june2009
*! Jean-Benoit Hardouin
************************************************************************************************************
* Raschtest: Rasch model, fit tests and graphical validation
*
* Historic:
* Version 1 (2003-06-30): Jean-Benoit Hardouin
* Version 2 (2003-07-07): Jean-Benoit Hardouin
* Version 3 (2004-01-02): Jean-Benoit Hardouin
* Version 4 (2004-01-21): Jean-Benoit Hardouin
* Version 5 (2004-01-24): Jean-Benoit Hardouin
* Version 6 (2004-02-05): Jean-Benoit Hardouin
* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
* Version 7 (2005-04-02) : Jean-Benoit Hardouin
* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin
* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin
* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin
* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin
* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
*
* Needed modules :
* raschtestv7jf version 8.1 (http://freeirt.free.fr)
* gammasym version 2.2 (http://www.freeirt.org)
* gausshermite version 1 (http://www.freeirt.org)
* geekel2d version 4.3 (http://www.freeirt.org)
* genscore version 1.4 (http://www.freeirt.org)
* ghquadm (findit ghquadm)
* gllamm version 2.3.14 (ssc describe gllamm)
* gllapred version 2.3.7 (ssc describe gllapred)
* elapse (ssc describe elapse)
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2003-2009 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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define raschtest2,eclass
syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) ]
local nbitems:word count `varlist'
if "`method'"=="" {
local method "cml"
}
else {
local method=lower("`method'")
}
if "`test'"=="" {
local test "R"
}
else {
local test=upper("`test'")
}
if "`dirsave'"!="" {
local dirsavev8 "dirsave(`dirsave')"
}
if "`method'"!="" {
local methodv8 "method(`method')"
}
if "`test'"!="" {
local testv8 "test(`test')"
}
if "`group'"!="" {
local groupv8 "group(`group')"
}
if "`genlt'"!="" {
local genltv8 "genlt(`genlt')"
}
if "`genscore'"!="" {
local genscorev8 "genscore(`genscore')"
}
if "`genfit'"!="" {
local genfitv8 "genfit(`genfit')"
}
if "`comp'"!="" {
local compv8 "comp(`comp')"
}
if "`dif'"!="" {
local difv8 "dif(`dif')"
}
if "`iterate'"!="" {
local iteratev8 "iterate(`iterate')"
}
if "`difficulties'"!="" {
local difficultiesv8 "difficulties(`difficulties')"
}
if "`covariates'"!="" {
local covariatesv8 "covariates(`covariates')"
}
raschtestv7jf `varlist' `if' `in' , id(`id') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8'
/***********************************************************************************************************
RETURN
************************************************************************************************************/
ereturn clear
if `nbitems'>=3 {
if "`method'"=="cml" {
if "`test'"!="none" {
tempname AndersenZv8
matrix `AndersenZv8'=r(AndersenZ)
ereturn matrix AndersenZ=`AndersenZv8'
}
if "`dif'"!="" {
tempname DIFv8
matrix `DIFv8'=r(DIF)
ereturn matrix DIF=`DIFv8'
}
tempname cllv8
scalar `cllv8'=r(cll)
ereturn scalar cll=`cllv8'
}
if "`test'"!="NONE" {
tempname itemFitv8 globalFitv8
matrix `itemFitv8'=r(itemFit)
matrix `globalFitv8'=r(globalFit)
ereturn matrix itemFit=`itemFitv8'
ereturn matrix globalFit=`globalFitv8'
}
}
if "`method'"!="cml" {
tempname sigmav8 sesigmav8
local `sigmav8'=`r(sigma)'
local `sesigmav8'=`r(sesigma)'
ereturn scalar sigma=``sigmav8''
ereturn scalar sesigma=``sesigmav8''
}
tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
matrix `betav8'=r(beta)
matrix `Varbetav8'=r(Varbeta)
ereturn matrix beta=`betav8'
ereturn matrix Varbeta=`Varbetav8'
matrix `thetav8'=r(theta)
matrix `Varthetav8'=r(Vartheta)
ereturn matrix theta=`thetav8'
ereturn matrix Vartheta=`Varthetav8'
scalar `llv8'=`r(ll)'
scalar `AICv8'=`r(AIC)'
ereturn scalar ll=`llv8'
ereturn scalar AIC=`AICv8'
ereturn scalar Zcomp=r(Zcomp)
ereturn scalar pZcomp=r(pZcomp)
if "`method'"=="mml" {
local psi=r(PSI)
local psiadj=r(PSIadj)
ereturn scalar PSI=`psi'
ereturn scalar PSIadj=`psiadj'
}
if "`covariates'"!="" {
tempname betacovariates Vbetacovariates zcovariates pcovariates
matrix `betacovariates'=r(betacovariates)
matrix `Vbetacovariates'=r(Vbetacovariates)
matrix `zcovariates'=r(zcovariates)
matrix `pcovariates'=r(pcovariates)
ereturn matrix betacovariates=`betacovariates'
ereturn matrix Vbetacovariates=`Vbetacovariates'
ereturn matrix zcovariates=`zcovariates'
ereturn matrix pcovariates=`pcovariates'
}
return clear
end

View File

@ -0,0 +1,200 @@
*! version 8 25june2009
*! Jean-Benoit Hardouin
************************************************************************************************************
* Raschtest: Rasch model, fit tests and graphical validation
*
* Historic:
* Version 1 (2003-06-30): Jean-Benoit Hardouin
* Version 2 (2003-07-07): Jean-Benoit Hardouin
* Version 3 (2004-01-02): Jean-Benoit Hardouin
* Version 4 (2004-01-21): Jean-Benoit Hardouin
* Version 5 (2004-01-24): Jean-Benoit Hardouin
* Version 6 (2004-02-05): Jean-Benoit Hardouin
* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
* Version 7 (2005-04-02) : Jean-Benoit Hardouin
* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin
* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin
* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin
* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin
* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
*
* Needed modules :
* raschtestv7 version 8.1 (http://freeirt.free.fr)
* gammasym version 2.2 (http://www.freeirt.org)
* gausshermite version 1 (http://www.freeirt.org)
* geekel2d version 4.3 (http://www.freeirt.org)
* genscore version 1.4 (http://www.freeirt.org)
* ghquadm (findit ghquadm)
* gllamm version 2.3.14 (ssc describe gllamm)
* gllapred version 2.3.7 (ssc describe gllapred)
* elapse (ssc describe elapse)
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2003-2009 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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define raschtest,eclass
syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) ]
local nbitems:word count `varlist'
if "`method'"=="" {
local method "cml"
}
else {
local method=lower("`method'")
}
if "`test'"=="" {
local test "R"
}
else {
local test=upper("`test'")
}
if "`dirsave'"!="" {
local dirsavev8 "dirsave(`dirsave')"
}
if "`method'"!="" {
local methodv8 "method(`method')"
}
if "`test'"!="" {
local testv8 "test(`test')"
}
if "`group'"!="" {
local groupv8 "group(`group')"
}
if "`genlt'"!="" {
local genltv8 "genlt(`genlt')"
}
if "`genscore'"!="" {
local genscorev8 "genscore(`genscore')"
}
if "`genfit'"!="" {
local genfitv8 "genfit(`genfit')"
}
if "`comp'"!="" {
local compv8 "comp(`comp')"
}
if "`dif'"!="" {
local difv8 "dif(`dif')"
}
if "`iterate'"!="" {
local iteratev8 "iterate(`iterate')"
}
if "`difficulties'"!="" {
local difficultiesv8 "difficulties(`difficulties')"
}
if "`covariates'"!="" {
local covariatesv8 "covariates(`covariates')"
}
raschtestv7 `varlist' `if' `in' , id(`id') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8'
/***********************************************************************************************************
RETURN
************************************************************************************************************/
ereturn clear
if `nbitems'>=3 {
if "`method'"=="cml" {
if "`test'"!="none" {
tempname AndersenZv8
matrix `AndersenZv8'=r(AndersenZ)
ereturn matrix AndersenZ=`AndersenZv8'
}
if "`dif'"!="" {
tempname DIFv8
matrix `DIFv8'=r(DIF)
ereturn matrix DIF=`DIFv8'
}
tempname cllv8
scalar `cllv8'=r(cll)
ereturn scalar cll=`cllv8'
}
if "`test'"!="NONE" {
tempname itemFitv8 globalFitv8
matrix `itemFitv8'=r(itemFit)
matrix `globalFitv8'=r(globalFit)
ereturn matrix itemFit=`itemFitv8'
ereturn matrix globalFit=`globalFitv8'
}
}
if "`method'"!="cml" {
tempname sigmav8 sesigmav8
local `sigmav8'=`r(sigma)'
local `sesigmav8'=`r(sesigma)'
ereturn scalar sigma=``sigmav8''
ereturn scalar sesigma=``sesigmav8''
}
tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
matrix `betav8'=r(beta)
matrix `Varbetav8'=r(Varbeta)
ereturn matrix beta=`betav8'
ereturn matrix Varbeta=`Varbetav8'
matrix `thetav8'=r(theta)
matrix `Varthetav8'=r(Vartheta)
ereturn matrix theta=`thetav8'
ereturn matrix Vartheta=`Varthetav8'
scalar `llv8'=`r(ll)'
scalar `AICv8'=`r(AIC)'
ereturn scalar ll=`llv8'
ereturn scalar AIC=`AICv8'
ereturn scalar Zcomp=r(Zcomp)
ereturn scalar pZcomp=r(pZcomp)
if "`method'"=="mml" {
local psi=r(PSI)
local psiadj=r(PSIadj)
ereturn scalar PSI=`psi'
ereturn scalar PSIadj=`psiadj'
}
if "`covariates'"!="" {
tempname betacovariates Vbetacovariates zcovariates pcovariates
matrix `betacovariates'=r(betacovariates)
matrix `Vbetacovariates'=r(Vbetacovariates)
matrix `zcovariates'=r(zcovariates)
matrix `pcovariates'=r(pcovariates)
ereturn matrix betacovariates=`betacovariates'
ereturn matrix Vbetacovariates=`Vbetacovariates'
ereturn matrix zcovariates=`zcovariates'
ereturn matrix pcovariates=`pcovariates'
}
return clear
end

View File

@ -0,0 +1,204 @@
*! version 8.3 15june2010
*! Jean-Benoit Hardouin
************************************************************************************************************
* Raschtest: Rasch model, fit tests and graphical validation
*
* Historic:
* Version 1 (2003-06-30): Jean-Benoit Hardouin
* Version 2 (2003-07-07): Jean-Benoit Hardouin
* Version 3 (2004-01-02): Jean-Benoit Hardouin
* Version 4 (2004-01-21): Jean-Benoit Hardouin
* Version 5 (2004-01-24): Jean-Benoit Hardouin
* Version 6 (2004-02-05): Jean-Benoit Hardouin
* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
* Version 7 (2005-04-02) : Jean-Benoit Hardouin
* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin
* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin
* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin
* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin
* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
* Version 8.3 (2009-06-20) : Jean-Benoit Hardouin /*GENRES option*/
*
* Needed modules :
* raschtestv7 version 8.1 (http://freeirt.free.fr)
* gammasym version 2.2 (http://www.freeirt.org)
* gausshermite version 1 (http://www.freeirt.org)
* geekel2d version 4.3 (http://www.freeirt.org)
* genscore version 1.4 (http://www.freeirt.org)
* ghquadm (findit ghquadm)
* gllamm version 2.3.14 (ssc describe gllamm)
* gllapred version 2.3.7 (ssc describe gllapred)
* elapse (ssc describe elapse)
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2003-2009 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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define raschtest,eclass
syntax varlist(min=1 numeric) [if] [in] , ID(varname) [ MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string)]
local nbitems:word count `varlist'
if "`method'"=="" {
local method "cml"
}
else {
local method=lower("`method'")
}
if "`test'"=="" {
local test "R"
}
else {
local test=upper("`test'")
}
if "`dirsave'"!="" {
local dirsavev8 "dirsave(`dirsave')"
}
if "`method'"!="" {
local methodv8 "method(`method')"
}
if "`test'"!="" {
local testv8 "test(`test')"
}
if "`group'"!="" {
local groupv8 "group(`group')"
}
if "`genlt'"!="" {
local genltv8 "genlt(`genlt')"
}
if "`genscore'"!="" {
local genscorev8 "genscore(`genscore')"
}
if "`genres'"!="" {
local gensresv8 "genres(`genres')"
}
if "`genfit'"!="" {
local genfitv8 "genfit(`genfit')"
}
if "`comp'"!="" {
local compv8 "comp(`comp')"
}
if "`dif'"!="" {
local difv8 "dif(`dif')"
}
if "`iterate'"!="" {
local iteratev8 "iterate(`iterate')"
}
if "`difficulties'"!="" {
local difficultiesv8 "difficulties(`difficulties')"
}
if "`covariates'"!="" {
local covariatesv8 "covariates(`covariates')"
}
raschtestv7 `varlist' `if' `in' , id(`id') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8'
/***********************************************************************************************************
RETURN
************************************************************************************************************/
ereturn clear
if `nbitems'>=3 {
if "`method'"=="cml" {
if "`test'"!="none" {
tempname AndersenZv8
matrix `AndersenZv8'=r(AndersenZ)
ereturn matrix AndersenZ=`AndersenZv8'
}
if "`dif'"!="" {
tempname DIFv8
matrix `DIFv8'=r(DIF)
ereturn matrix DIF=`DIFv8'
}
tempname cllv8
scalar `cllv8'=r(cll)
ereturn scalar cll=`cllv8'
}
if "`test'"!="NONE" {
tempname itemFitv8 globalFitv8
matrix `itemFitv8'=r(itemFit)
matrix `globalFitv8'=r(globalFit)
ereturn matrix itemFit=`itemFitv8'
ereturn matrix globalFit=`globalFitv8'
}
}
if "`method'"!="cml" {
tempname sigmav8 sesigmav8
local `sigmav8'=`r(sigma)'
local `sesigmav8'=`r(sesigma)'
ereturn scalar sigma=``sigmav8''
ereturn scalar sesigma=``sesigmav8''
}
tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
matrix `betav8'=r(beta)
matrix `Varbetav8'=r(Varbeta)
ereturn matrix beta=`betav8'
ereturn matrix Varbeta=`Varbetav8'
matrix `thetav8'=r(theta)
matrix `Varthetav8'=r(Vartheta)
ereturn matrix theta=`thetav8'
ereturn matrix Vartheta=`Varthetav8'
scalar `llv8'=`r(ll)'
scalar `AICv8'=`r(AIC)'
ereturn scalar ll=`llv8'
ereturn scalar AIC=`AICv8'
ereturn scalar Zcomp=r(Zcomp)
ereturn scalar pZcomp=r(pZcomp)
if "`method'"=="mml" {
local psi=r(PSI)
local psiadj=r(PSIadj)
ereturn scalar PSI=`psi'
ereturn scalar PSIadj=`psiadj'
}
if "`covariates'"!="" {
tempname betacovariates Vbetacovariates zcovariates pcovariates
matrix `betacovariates'=r(betacovariates)
matrix `Vbetacovariates'=r(Vbetacovariates)
matrix `zcovariates'=r(zcovariates)
matrix `pcovariates'=r(pcovariates)
ereturn matrix betacovariates=`betacovariates'
ereturn matrix Vbetacovariates=`Vbetacovariates'
ereturn matrix zcovariates=`zcovariates'
ereturn matrix pcovariates=`pcovariates'
}
return clear
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,584 @@
*! version 1 25februar2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* rsoort: Response Shift detection with the Oort procedure
*
* Historic:
* Version 1 (2013-02-25): Jean-Benoit Hardouin
*
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
* jean-benoit.hardouin@univ-nantes.fr
*
* Copyright 2013 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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define rsoort,eclass
syntax varlist(min=1 numeric) [if] [in] [,METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPriorisation(varlist) noSearch]
tokenize `varlist'
local nbitems:word count `varlist'
local mod=mod(`nbitems',2)
if `mod'!=0 {
di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
error
}
if "`method'"=="" {
local method "ml"
}
local nbitems=`nbitems'/2
di _col(20) "{hline 30}"
di _col(20) in gr "Time 1" _col(40) "Time 2"
di _col(20) "{hline 30}"
forvalues i=1/`nbitems' {
di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
}
di _col(20) "{hline 30}"
/**************************************************************************************************************
Model 1
***************************************************************************************************************/
qui sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method')
qui estat gof, stat(all)
local tli1=r(tli)
local cfi1=r(cfi)
local srmr1=r(srmr)
local rmsea1=r(rmsea)
local ubrmsea1=r(ub90_rmsea)
local lbrmsea1=r(lb90_rmsea)
local chi21=r(chi2_ms)
local df1=r(df_ms)
local dfc1=6*`nbitems'+1
local p1=r(p_ms)
*di
*di in green " ***********************************Model 1********************************************"
*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
/**************************************************************************************************************
Model 2
***************************************************************************************************************/
local sem
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local sem `sem' `sem`i''
local var `var' `var`i''
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange2=`b'[1,`=`nbitems'*4+1']
local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof, stat(all)
local tli2=r(tli)
local cfi2=r(cfi)
local srmr2=r(srmr)
local rmsea2=r(rmsea)
local ubrmsea2=r(ub90_rmsea)
local lbrmsea2=r(lb90_rmsea)
local chi22=r(chi2_ms)
local df2=r(df_ms)
local dfc2=3*`nbitems'+3
local p2=r(p_ms)
local chi221=abs(`chi21'-`chi22')
local df21=`df2'-`df1'
local p21=1-chi2(`df21',`chi221')
di "{hline 105}"
di in gr _col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"
di in gr "Models" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
di in gr "Model 1" _col(20) %8.2f in ye `chi21'
di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' _col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'
di "{hline 105}"
/**************************************************************************************************************
Model 3
***************************************************************************************************************/
/**************************************************************************************************************
Model 3 / Non uniform recalibration
***************************************************************************************************************/
tempname RS RSprec
qui matrix `RS'=J(`nbitems',3,0)
qui matrix `RSprec'=J(`nbitems',3,0)
local df3=`dfc2'
*set trace on
forvalues i=1/`nbitems' {
local nbUR:word count `uniformrecalibration'
forvalues j=1/`nbUR' {
local itemj: word `j' of `uniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',2]=1
}
}
local nbNUR:word count `nonuniformrecalibration'
forvalues j=1/`nbNUR' {
local itemj: word `j' of `nonuniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',1]=1
}
}
local nbR:word count `repriorisation'
forvalues j=1/`nbR' {
local itemj: word `j' of `repriorisation'
if "``i''"=="`itemj'" {
matrix `RS'[`i',3]=1
}
}
}
matrix list `RS'
if "`search'"=="" {
di
di "{hline 105}"
di in green _col(50) "Model 3"
di "{hline 105}"
di
di in white _col(10) "Non uniform Recalibration"
local continue=1
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
}
local prec_chi2=`chi22'
local testNU_varchi2=0
local testNU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testNU_varchi2_temp=0
local testNU_p_temp=0
local testNU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
local var
forvalues j=1/`nbitems' {
local sem
local var
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',1]==0&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `var`i''
}
if `RS'[`i',1]==1&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==0 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==1 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
local continue=1
local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
local testNU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
local ++cpt
}
}
if (`testNU_item_temp'!=0) {
matrix `RS'[`testNU_item_temp',1]=1
local ++df3
local testNU_varchi2=`testNU_varchi2_temp'
local testNU_p=`testNU_p_temp'
local testNU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
/**************************************************************************************************************
Model 3 / Uniform recalibration
***************************************************************************************************************/
di
di in white _col(10) "Uniform Recalibration"
local continue=1
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testU_varchi2_temp=0
local testU_p_temp=0
local testU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
if `RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==0 {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==1 {
local sem `sem' `semrecU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
local continue=1
local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
local testU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
local ++cpt
}
}
if (`testU_item_temp'!=0) {
matrix `RS'[`testU_item_temp',2]=1
local ++df3
local testU_varchi2=`testU_varchi2_temp'
local testU_p=`testU_p_temp'
local testU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
/**************************************************************************************************************
Model 3 / Repriorisation
***************************************************************************************************************/
di
di in white _col(10) "Repriorisation"
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testR_varchi2_temp=0
local testR_p_temp=0
local testR_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `semrep`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
local sem `sem' `semrecUrep`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
local continue=1
local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
local testR_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
}
else {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) "Anavailable"
}
local ++cpt
}
}
if (`testR_item_temp'!=0) {
matrix `RS'[`testR_item_temp',3]=1
local ++df3
local testR_varchi2=`testR_varchi2_temp'
local testR_p=`testR_p_temp'
local testR_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
}
/**************************************************************************************************************
Model 3 Final
***************************************************************************************************************/
di
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==0 {
local sem "`sem' `sem`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==1 {
local sem "`sem' `semrep`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==0 {
local sem "`sem' `semrecU`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==1 {
local sem "`sem' `semrecUrep`i''"
}
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof
local tli3=r(tli)
local cfi3=r(cfi)
local srmr3=r(srmr)
local rmsea3=r(rmsea)
local ubrmsea3=r(ub90_rmsea)
local lbrmsea3=r(lb90_rmsea)
local chi23=r(chi2_ms)
local dfc3=`df3'
local p3=r(p_ms)
/**************************************************************************************************************
Bilan
***************************************************************************************************************/
di
di "{hline 74}"
di in gr _col(22) "Non uniform" _col(46) "Uniform"
di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(60) "Repriorisation"
di "{hline 74}"
forvalues i=1/`nbitems' {
local recNU
local recU
local rep
if (`RS'[`i',1]==1) {
local recNU "*"
}
if (`RS'[`i',2]==1) {
local recU "*"
}
if (`RS'[`i',3]==1) {
local rep "*"
}
di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
}
di "{hline 74}"
/**************************************************************************************************************
Model 4
***************************************************************************************************************/
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100)
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof,stat(all)
local tli4=r(tli)
local cfi4=r(cfi)
local srmr4=r(srmr)
local rmsea4=r(rmsea)
local ubrmsea4=r(ub90_rmsea)
local lbrmsea4=r(lb90_rmsea)
local chi24=r(chi2_ms)
local dfc4=`df3'+1
local p4=r(p_ms)
local chi2encours=r(chi2_ms)
local z=`truechange'/sqrt(`Vtruechange')
di
di "{hline 95}"
di in gr "Models" _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
di "{hline 95}"
di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `dfc2' _col(30) %6.4f `p2' _col(40) %6.4f `rmsea2' _col(50) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `dfc4' _col(30) %6.4f `p4' _col(40) %6.4f `rmsea4' _col(50) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
di "{hline 95}"
di
di "{hline 77}"
di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
di "{hline 77}"
di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
di "{hline 77}"
di
end

View File

@ -0,0 +1,584 @@
*! version 1 25februar2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* rsoort: Response Shift detection with the Oort procedure
*
* Historic:
* Version 1 (2013-02-25): Jean-Benoit Hardouin
*
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
* jean-benoit.hardouin@univ-nantes.fr
*
* Copyright 2013 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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define rsoort,eclass
syntax varlist(min=1 numeric) [if] [in] [,METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPriorisation(varlist) noSearch]
tokenize `varlist'
local nbitems:word count `varlist'
local mod=mod(`nbitems',2)
if `mod'!=0 {
di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
error
}
if "`method'"=="" {
local method "ml"
}
local nbitems=`nbitems'/2
di _col(20) "{hline 30}"
di _col(20) in gr "Time 1" _col(40) "Time 2"
di _col(20) "{hline 30}"
forvalues i=1/`nbitems' {
di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
}
di _col(20) "{hline 30}"
/**************************************************************************************************************
Model 1
***************************************************************************************************************/
qui sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method')
qui estat gof, stat(all)
local tli1=r(tli)
local cfi1=r(cfi)
local srmr1=r(srmr)
local rmsea1=r(rmsea)
local ubrmsea1=r(ub90_rmsea)
local lbrmsea1=r(lb90_rmsea)
local chi21=r(chi2_ms)
local df1=r(df_ms)
local dfc1=6*`nbitems'+1
local p1=r(p_ms)
*di
*di in green " ***********************************Model 1********************************************"
*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
/**************************************************************************************************************
Model 2
***************************************************************************************************************/
local sem
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local sem `sem' `sem`i''
local var `var' `var`i''
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange2=`b'[1,`=`nbitems'*4+1']
local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof, stat(all)
local tli2=r(tli)
local cfi2=r(cfi)
local srmr2=r(srmr)
local rmsea2=r(rmsea)
local ubrmsea2=r(ub90_rmsea)
local lbrmsea2=r(lb90_rmsea)
local chi22=r(chi2_ms)
local df2=r(df_ms)
local dfc2=3*`nbitems'+3
local p2=r(p_ms)
local chi221=abs(`chi21'-`chi22')
local df21=`df2'-`df1'
local p21=1-chi2(`df21',`chi221')
di "{hline 105}"
di in gr _col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"
di in gr "Models" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
di in gr "Model 1" _col(20) %8.2f in ye `chi21'
di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' _col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'
di "{hline 105}"
/**************************************************************************************************************
Model 3
***************************************************************************************************************/
/**************************************************************************************************************
Model 3 / Non uniform recalibration
***************************************************************************************************************/
tempname RS RSprec
qui matrix `RS'=J(`nbitems',3,0)
qui matrix `RSprec'=J(`nbitems',3,0)
local df3=`dfc2'
*set trace on
forvalues i=1/`nbitems' {
local nbUR:word count `uniformrecalibration'
forvalues j=1/`nbUR' {
local itemj: word `j' of `uniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',2]=1
}
}
local nbNUR:word count `nonuniformrecalibration'
forvalues j=1/`nbNUR' {
local itemj: word `j' of `nonuniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',1]=1
}
}
local nbR:word count `repriorisation'
forvalues j=1/`nbR' {
local itemj: word `j' of `repriorisation'
if "``i''"=="`itemj'" {
matrix `RS'[`i',3]=1
}
}
}
matrix list `RS'
if "`search'"=="" {
di
di "{hline 105}"
di in green _col(50) "Model 3"
di "{hline 105}"
di
di in white _col(10) "Non uniform Recalibration"
local continue=1
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
}
local prec_chi2=`chi22'
local testNU_varchi2=0
local testNU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testNU_varchi2_temp=0
local testNU_p_temp=0
local testNU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
local var
forvalues j=1/`nbitems' {
local sem
local var
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',1]==0&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `var`i''
}
if `RS'[`i',1]==1&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==0 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==1 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
local continue=1
local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
local testNU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
local ++cpt
}
}
if (`testNU_item_temp'!=0) {
matrix `RS'[`testNU_item_temp',1]=1
local ++df3
local testNU_varchi2=`testNU_varchi2_temp'
local testNU_p=`testNU_p_temp'
local testNU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
/**************************************************************************************************************
Model 3 / Uniform recalibration
***************************************************************************************************************/
di
di in white _col(10) "Uniform Recalibration"
local continue=1
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testU_varchi2_temp=0
local testU_p_temp=0
local testU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
if `RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==0 {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==1 {
local sem `sem' `semrecU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
local continue=1
local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
local testU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
local ++cpt
}
}
if (`testU_item_temp'!=0) {
matrix `RS'[`testU_item_temp',2]=1
local ++df3
local testU_varchi2=`testU_varchi2_temp'
local testU_p=`testU_p_temp'
local testU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
/**************************************************************************************************************
Model 3 / Repriorisation
***************************************************************************************************************/
di
di in white _col(10) "Repriorisation"
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testR_varchi2_temp=0
local testR_p_temp=0
local testR_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `semrep`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
local sem `sem' `semrecUrep`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
local continue=1
local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
local testR_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
}
else {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) "Anavailable"
}
local ++cpt
}
}
if (`testR_item_temp'!=0) {
matrix `RS'[`testR_item_temp',3]=1
local ++df3
local testR_varchi2=`testR_varchi2_temp'
local testR_p=`testR_p_temp'
local testR_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
}
/**************************************************************************************************************
Model 3 Final
***************************************************************************************************************/
di
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==0 {
local sem "`sem' `sem`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==1 {
local sem "`sem' `semrep`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==0 {
local sem "`sem' `semrecU`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==1 {
local sem "`sem' `semrecUrep`i''"
}
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof
local tli3=r(tli)
local cfi3=r(cfi)
local srmr3=r(srmr)
local rmsea3=r(rmsea)
local ubrmsea3=r(ub90_rmsea)
local lbrmsea3=r(lb90_rmsea)
local chi23=r(chi2_ms)
local dfc3=`df3'
local p3=r(p_ms)
/**************************************************************************************************************
Bilan
***************************************************************************************************************/
di
di "{hline 74}"
di in gr _col(22) "Non uniform" _col(46) "Uniform"
di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(60) "Repriorisation"
di "{hline 74}"
forvalues i=1/`nbitems' {
local recNU
local recU
local rep
if (`RS'[`i',1]==1) {
local recNU "*"
}
if (`RS'[`i',2]==1) {
local recU "*"
}
if (`RS'[`i',3]==1) {
local rep "*"
}
di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
}
di "{hline 74}"
/**************************************************************************************************************
Model 4
***************************************************************************************************************/
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100)
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof,stat(all)
local tli4=r(tli)
local cfi4=r(cfi)
local srmr4=r(srmr)
local rmsea4=r(rmsea)
local ubrmsea4=r(ub90_rmsea)
local lbrmsea4=r(lb90_rmsea)
local chi24=r(chi2_ms)
local dfc4=`df3'+1
local p4=r(p_ms)
local chi2encours=r(chi2_ms)
local z=`truechange'/sqrt(`Vtruechange')
di
di "{hline 95}"
di in gr "Models" _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
di "{hline 95}"
di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `dfc2' _col(30) %6.4f `p2' _col(40) %6.4f `rmsea2' _col(50) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `dfc4' _col(30) %6.4f `p4' _col(40) %6.4f `rmsea4' _col(50) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
di "{hline 95}"
di
di "{hline 77}"
di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
di "{hline 77}"
di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
di "{hline 77}"
di
end

View File

@ -0,0 +1,584 @@
*! version 1 25februar2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* rsoort: Response Shift detection with the Oort procedure
*
* Historic:
* Version 1 (2013-02-25): Jean-Benoit Hardouin
*
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
* jean-benoit.hardouin@univ-nantes.fr
*
* Copyright 2013 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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define rsoort,eclass
syntax varlist(min=1 numeric) [if] [in] [,METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPriorisation(varlist) noSearch]
tokenize `varlist'
local nbitems:word count `varlist'
local mod=mod(`nbitems',2)
if `mod'!=0 {
di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
error
}
if "`method'"=="" {
local method "ml"
}
local nbitems=`nbitems'/2
di _col(20) "{hline 30}"
di _col(20) in gr "Time 1" _col(40) "Time 2"
di _col(20) "{hline 30}"
forvalues i=1/`nbitems' {
di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
}
di _col(20) "{hline 30}"
/**************************************************************************************************************
Model 1
***************************************************************************************************************/
qui sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method')
qui estat gof, stat(all)
local tli1=r(tli)
local cfi1=r(cfi)
local srmr1=r(srmr)
local rmsea1=r(rmsea)
local ubrmsea1=r(ub90_rmsea)
local lbrmsea1=r(lb90_rmsea)
local chi21=r(chi2_ms)
local df1=r(df_ms)
local dfc1=6*`nbitems'+1
local p1=r(p_ms)
*di
*di in green " ***********************************Model 1********************************************"
*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
/**************************************************************************************************************
Model 2
***************************************************************************************************************/
local sem
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local sem `sem' `sem`i''
local var `var' `var`i''
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange2=`b'[1,`=`nbitems'*4+1']
local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof, stat(all)
local tli2=r(tli)
local cfi2=r(cfi)
local srmr2=r(srmr)
local rmsea2=r(rmsea)
local ubrmsea2=r(ub90_rmsea)
local lbrmsea2=r(lb90_rmsea)
local chi22=r(chi2_ms)
local df2=r(df_ms)
local dfc2=3*`nbitems'+3
local p2=r(p_ms)
local chi221=abs(`chi21'-`chi22')
local df21=`df2'-`df1'
local p21=1-chi2(`df21',`chi221')
di "{hline 105}"
di in gr _col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"
di in gr "Models" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
di in gr "Model 1" _col(20) %8.2f in ye `chi21'
di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' _col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'
di "{hline 105}"
/**************************************************************************************************************
Model 3
***************************************************************************************************************/
/**************************************************************************************************************
Model 3 / Non uniform recalibration
***************************************************************************************************************/
tempname RS RSprec
qui matrix `RS'=J(`nbitems',3,0)
qui matrix `RSprec'=J(`nbitems',3,0)
local df3=`dfc2'
*set trace on
forvalues i=1/`nbitems' {
local nbUR:word count `uniformrecalibration'
forvalues j=1/`nbUR' {
local itemj: word `j' of `uniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',2]=1
}
}
local nbNUR:word count `nonuniformrecalibration'
forvalues j=1/`nbNUR' {
local itemj: word `j' of `nonuniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',1]=1
}
}
local nbR:word count `repriorisation'
forvalues j=1/`nbR' {
local itemj: word `j' of `repriorisation'
if "``i''"=="`itemj'" {
matrix `RS'[`i',3]=1
}
}
}
matrix list `RS'
if "`search'"=="" {
di
di "{hline 105}"
di in green _col(50) "Model 3"
di "{hline 105}"
di
di in white _col(10) "Non uniform Recalibration"
local continue=1
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
}
local prec_chi2=`chi22'
local testNU_varchi2=0
local testNU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testNU_varchi2_temp=0
local testNU_p_temp=0
local testNU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
local var
forvalues j=1/`nbitems' {
local sem
local var
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',1]==0&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `var`i''
}
if `RS'[`i',1]==1&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==0 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==1 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
local continue=1
local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
local testNU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
local ++cpt
}
}
if (`testNU_item_temp'!=0) {
matrix `RS'[`testNU_item_temp',1]=1
local ++df3
local testNU_varchi2=`testNU_varchi2_temp'
local testNU_p=`testNU_p_temp'
local testNU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
/**************************************************************************************************************
Model 3 / Uniform recalibration
***************************************************************************************************************/
di
di in white _col(10) "Uniform Recalibration"
local continue=1
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testU_varchi2_temp=0
local testU_p_temp=0
local testU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
if `RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==0 {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==1 {
local sem `sem' `semrecU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
local continue=1
local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
local testU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
local ++cpt
}
}
if (`testU_item_temp'!=0) {
matrix `RS'[`testU_item_temp',2]=1
local ++df3
local testU_varchi2=`testU_varchi2_temp'
local testU_p=`testU_p_temp'
local testU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
/**************************************************************************************************************
Model 3 / Repriorisation
***************************************************************************************************************/
di
di in white _col(10) "Repriorisation"
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
di "{hline 105}"
di in gr _col(39) "Comparison with previous model" _col(79) "Comparison with model 1"
di in gr "Items" _col(18) "Chi-square" _col(39) "Chi-square" _col(54) "df" _col(59) "p-value" _col(79) "Chi-square" _col(94) "df" _col(99) "p-value"
di "{hline 105}"
while (`continue') {
local cpt=0
local testR_varchi2_temp=0
local testR_p_temp=0
local testR_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `semrep`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
local sem `sem' `semrecUrep`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
qui estat gof
local chi2encours=r(chi2_ms)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
local continue=1
local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
local testR_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(55) "1" %6.4f _col(60) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' _col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'
}
else {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) "Anavailable"
}
local ++cpt
}
}
if (`testR_item_temp'!=0) {
matrix `RS'[`testR_item_temp',3]=1
local ++df3
local testR_varchi2=`testR_varchi2_temp'
local testR_p=`testR_p_temp'
local testR_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
di "{hline 105}"
}
}
}
/**************************************************************************************************************
Model 3 Final
***************************************************************************************************************/
di
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==0 {
local sem "`sem' `sem`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==1 {
local sem "`sem' `semrep`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==0 {
local sem "`sem' `semrecU`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==1 {
local sem "`sem' `semrecUrep`i''"
}
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof
local tli3=r(tli)
local cfi3=r(cfi)
local srmr3=r(srmr)
local rmsea3=r(rmsea)
local ubrmsea3=r(ub90_rmsea)
local lbrmsea3=r(lb90_rmsea)
local chi23=r(chi2_ms)
local dfc3=`df3'
local p3=r(p_ms)
/**************************************************************************************************************
Bilan
***************************************************************************************************************/
di
di "{hline 74}"
di in gr _col(22) "Non uniform" _col(46) "Uniform"
di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(60) "Repriorisation"
di "{hline 74}"
forvalues i=1/`nbitems' {
local recNU
local recU
local rep
if (`RS'[`i',1]==1) {
local recNU "*"
}
if (`RS'[`i',2]==1) {
local recU "*"
}
if (`RS'[`i',3]==1) {
local rep "*"
}
di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
}
di "{hline 74}"
/**************************************************************************************************************
Model 4
***************************************************************************************************************/
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100)
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof,stat(all)
local tli4=r(tli)
local cfi4=r(cfi)
local srmr4=r(srmr)
local rmsea4=r(rmsea)
local ubrmsea4=r(ub90_rmsea)
local lbrmsea4=r(lb90_rmsea)
local chi24=r(chi2_ms)
local dfc4=`df3'+1
local p4=r(p_ms)
local chi2encours=r(chi2_ms)
local z=`truechange'/sqrt(`Vtruechange')
di
di "{hline 95}"
di in gr "Models" _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
di "{hline 95}"
di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `dfc2' _col(30) %6.4f `p2' _col(40) %6.4f `rmsea2' _col(50) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `dfc4' _col(30) %6.4f `p4' _col(40) %6.4f `rmsea4' _col(50) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
di "{hline 95}"
di
di "{hline 77}"
di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
di "{hline 77}"
di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
di "{hline 77}"
di
end

View File

@ -0,0 +1,340 @@
*! 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

View File

@ -0,0 +1,70 @@
{smcl}
{* 208December2005}{...}
{hline}
help for {hi:raschfit}{right:Jean-Benoit Hardouin}
{hline}
{title:The Raschfit procedure}
{p 8 14 2}{cmd:raschfit} {it:varlist} {cmd:,} [{cmdab:ker:nel}({it:#}) {cmdab:nbsc:ales}({it:#}) {cmdab:items:order}({it:keyword}) {cmdab:nofast}]
{title:Description}
{p 4 8 2}{cmd:raschfit} realizes the Raschfit algorithm defined by Hardouin and
Mesbah (2004). This method selects sub-scales of items which fit a
Rasch model. The method begin with a kernel of items (two or more items)
defined by the user. At each step, the method uses a new item and verifies if this
new item is explained by the same latent trait than the already selected items.
If not, the items is not selected. The former version of the Raschfit algorithm
is based on the comparison of two model: A Rasch model and a Multidimensional
Marginally Sufficient Rasch Model (MMSRM). These two models are compared by the
Akaike Information Criterion (AIC). A faster version of the algorithm (Raschfit-Fast)
compares the Rasch model and an adapted version of this model where the response
to the "new" item is not explained by the latent trait. Raschfit-Fast is executed
by default.
{title:Options}
{p 4 8 2}{cmd:kernel}({it:#}) defines the # first items of {it:varlist} as the kernel
of the first sub-scale (by default with {cmd:itemsorder}({it:order}), this number is
fixed to 2).
{p 4 8 2}{cmd:nbscales}({it:#}) defines the maximal number of sub-scales (by default,
only one sub-scale is selected).
{p 4 8 2}{cmd:itemsorder}({it:keyword}) defines the order of the items. If you type
{it:order}, the kernel is composed of the first items defined in {it:varlist},
and the items are tested in the same order than in {it:varlist}.
If you type {it:msp} or {it:mspinv}, a Mokken Scale Procedure is run under
the items (the {it:msp} and {it:loevH} Stata programs are necessary) and the
items are selected from the first order selected by this procedure to the last
one (with {it:msp}), or in the inverse order (with {it:mspinv}). The method {it:msp}
is generaly more robust, but is longer to run. By default, the program uses {it:msp}.
{p 4 8 2}{cmd:nofast} allows to execute the former version of the algorithm.
{title:Example}
{p 4 8 2}{cmd:. raschfit itemA* , itemsorder(order)}
{p 4 8 2}{cmd:. raschfit itemA1-itemA7 , itemsorder(msp) kernel(4) nofast}
{p 4 8 2}{cmd:. raschfit item* }
{title:References}
{p 4 8 2} Hardouin J.-B. and Mesbah M. {it:Clustering binary variables in subscales using an extended Rasch model and Akaike Information Criterion}, Communication in Statistics <20> Theory and methods}, {cmd:33}(6), pp. 1277-1294, 2004
{p 4 8 2} Hardouin J.-B. {it:Construction d'<27>chelles d'items unidimensionnelles en qualit<69> de vie (Item selection in unidimensional scale applied to the Quality of Life)}, PhD thesis of the University Ren<65> Descartes - Paris 5,
France, 201 pp, 2005
{p 4 8 2} Hardouin J.-B. and Mesbah M. {it:Fast Clustering of Binary Variables in Subscales}, Unpublished document, 2005.
{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@orscentre.org":jean-benoit.hardouin@orscentre.org}
and visit the websites {browse "http://anaqol.free.fr":AnaQol}
and {browse "http://freeirt.free.fr":FreeIRT}

View File

@ -0,0 +1,229 @@
*! version 1 : February 15th, 2012
*! Myriam Blanchin
************************************************************************************************************
* raschlong: Estimation of the parameters of a model of the Rasch family in a longitudinal setting
*
* Version 1 : February 15th, 2012: pcm et rasch, contraintes sur la matrice de variance-covariance et difficult<6C>s d'items fix<69>es
*
************************************************************************************************************/
program define raschlong,eclass
syntax varlist [, NBT(int 2) DIFFiculties(string) VAR(string) ]
*the dataset should be in wide format
*the matrix of difficulties should contain `nbit' rows and `nbmodpos' columns
*the item parameters are assumed to be constant with time
*same number of modalities for each item
*varlist should contain for each timepoint the list of variables containing the answers to the items - example: T1item1 T1item2 T1item3 T2item1 T2item2 T2item3
preserve
tempname diff varcov item id temps one obs estbeta estvar
/*di "item" "`item'"
di "temps" "`temps'"
di "obs" "`obs'"
di "diff" "`diff'"
di "varcov" "`varcov'"
di "id" "`id'"
di "one" "`one'"*/
*verif varlist
tokenize `varlist'
local nbittot:word count `varlist'
local nbit=`nbittot'/`nbt'
if `=int(`nbit')'!=`nbit'{
di in red "The number of variables should be equal to (the number of items * the number of timepoints). Please correct it."
error 198
exit
}
/*verif nb diff items*/
if "`difficulties'"!=""{
matrix `diff'=`difficulties'
if `nbit'!=`=rowsof(`diff')'{
di in red "The number of rows of the matrix of item parameters should be equal to the number of items. Please correct it."
error 198
exit
}
local nbmodat=colsof(`diff')+1
}
else{
local modcount=word("`varlist'",1)
qui tab `modcount'
local nbmodat=r(r)
}
*verif matcov
if "`var'"!=""{
matrix `varcov'=`var'
if `=rowsof(`var')'!=`nbt'{
di in red "The covariance matrix is incorrectly specified. Please correct it."
error 198
exit
}
}
qui{
*reshape of the dataset
gen `one'=1
collapse(sum) wt2=`one', by (`varlist')
*list in 1/3
forvalues t=1/`nbt'{
forvalues i=1/`nbit'{
local vartemp=word("`varlist'",`=(`t'-1)*`nbit'+`i'')
gen tps`t'item`i'=`vartemp'
}
}
gen `id'=_n
local list=""
forvalues i=1/`nbit'{
local list="`list' tps@item`i'"
}
reshape long `list', i(`id') j(`temps')
*list in 1/20
reshape long tpsitem, i(`id' `temps') j(`item')
*list in 1/20
drop if tpsitem==.
gen `obs'=_n
expand `nbmodat'
sort `id' `temps' `item' `obs'
*list in 1/20
tab `temps', gen(t)
forvalues t=1/`nbt'{
by `obs', sort: gen x`t'=(_n-1)*t`t'
}
gen chosen=.
forvalues t=1/`nbt'{
replace chosen=tpsitem==x`t' if `temps'==`t'
}
tab `item', gen(it)
if "`difficulties'"==""{
forvalues i=1/`nbit'{
forvalues g=1/`=`nbmodat'-1'{
gen d`i'_`g'=.
}
}
forvalues t=1/`nbt'{
forvalues i=1/`nbit'{
forvalues g=1/`=`nbmodat'-1'{
replace d`i'_`g'=-1*it`i'*(x`t'>=`g') if `temps'==`t'
}
}
}
}
else{
gen offset=0
forvalues t=1/`nbt'{
forvalues i=1/`nbit'{
local sumdiff=0
forvalues g=1/`=`nbmodat'-1'{
local sumdiff=`sumdiff'-`diff'[`i',`g']
replace offset=`sumdiff' if it`i'==1 & x`t'==`g'
}
}
}
}
*list in 1/25
local listeq ""
forvalues t=1/`nbt'{
eq slope`t':x`t'
local listeq "`listeq' slope`t'"
}
if "`var'"!=""{
matrix C=cholesky(`varcov')
constraint define 1 [__01_1]x1=`=C[1,1]'
constraint define 2 [__01_2]x2=`=C[2,2]'
constraint define 3 [__01_2_1]_cons=`=C[2,1]'
}
}
tempname b V
if "`difficulties'"==""{
if "`var'"==""{
gllamm x1-x`nbt' d1_1-d`nbit'_`=`nbmodat'-1',i(`id') eqs(`listeq') link(mlogit) expand(`obs' chosen o) weight(wt) nocons nrf(`nbt') adapt
}
else{
gllamm x1-x`nbt' d1_1-d`nbit'_`=`nbmodat'-1',i(`id') eqs(`listeq') link(mlogit) constraints(1 2 3) expand(`obs' chosen o) weight(wt) nocons nrf(`nbt') adapt
}
matrix `b'=e(b)
matrix EstDiff=J(`nbit',`=`nbmodat'-1',.)
forvalues j=1/`nbit'{
matrix EstDiff[`j',1]=`b'[1,`=`nbt'+(`j'-1)*(`nbmodat'-1)'..`=`nbt'-1+`j'*(`nbmodat'-1)']
}
}
else{
if "`var'"==""{
gllamm x1-x`nbt',i(`id') eqs(`listeq') link(mlogit) expand(`obs' chosen o) weight(wt) nocons nrf(`nbt') adapt offset(offset)
}
else{
gllamm x1-x`nbt',i(`id') eqs(`listeq') link(mlogit) constraints(1 2 3) expand(`obs' chosen o) weight(wt) nocons nrf(`nbt') adapt offset(offset)
}
matrix `b'=e(b)
}
matrix `V'=e(V)
matrix EstMu=`b'[1,1..`=`nbt'-1']
matrix Var=e(chol)*e(chol)'
matrix se2=vecdiag(`V'[1..`=`nbt'-1',1..`=`nbt'-1'])
/*if test
test x2=x3=0
r(chi2)
r(df)
r(p)
*/
di
di
di in gr "{hline 91}"
di in gr _col(39) "RASCH FAMILY MODEL"
di in gr "{hline 91}"
di in gr "Number of timepoints: " in ye `nbt'
di in gr "Number of items: " in ye `nbit'
di in gr "Number of modalities per item: " in ye `nbmodat'
di in gr "{hline 91}"
local collist ""
forvalues i=1/`=`nbmodat'-1'{
local collist "`collist' dj_`i'"
}
local rowlist ""
forvalues i=1/`nbit'{
local rowlist "`rowlist' item`i'"
}
if "`difficulties'"==""{
di in gr "Item parameters estimations:"
matrix colnames EstDiff = `collist'
matrix rownames EstDiff = `rowlist'
matrix list EstDiff,noheader format(%7.3f)
ereturn matrix Diff=EstDiff
}
else{
di in gr "Item parameters fixed to:"
matrix colnames `diff' = `collist'
matrix rownames `diff' = `rowlist'
matrix list `diff',noheader format(%7.3f)
ereturn matrix Diff=`diff'
}
di
di
if "`var'"==""{
di in gr "Covariance matrix estimations:"
}
else{
di in gr "Covariance matrix fixed to:"
}
matrix list Var,noheader nonames format(%7.3f)
di
di
di in gr "Time effect estimations:"
di in gr _col(19) "Coef" _col(29) "S.E."
forvalues t=1/`=`nbt'-1'{
di in gr "Time" `=`t'+1' in ye _col(16) %7.2f EstMu[1,`t'] _col(26) %7.2f `=sqrt(se2[1,`t'])'
}
ereturn matrix Var=Var
end

View File

@ -0,0 +1,210 @@
* 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 raschlongitudinal2,rclass
syntax [varlist] [, n(int 100) diff(string) Mu(string) Sigma(string) Nodes(int 12) fast]
version 11
tempfile raschlongitudinalfile
capture qui save "`raschlongitudinalfile'",replace
if "`diff'"=="" {
tempname diff
*matrix `diff'=[-1\0\1]
matrix `diff'=[-1\-.5\0\.5\1]
}
if "`mu'"=="" {
tempname mu
matrix `mu'=[0,0]
}
if "`sigma'"=="" {
tempname sigma
matrix `sigma'=[1,0\0,1]
}
local nbitems=rowsof(`diff')
*local J=rowsof(`diff')+1
*local Nbit=rowsof(`diff')*2
di in gr "Number of individuals in the study: " in ye `n'
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: " _c
tempname dt
matrix `dt'=`diff' ' ''
matrix list `dt',noblank nohalf nonames noheader
di in green "mean of the latent traits: " _c
matrix list `mu',noblank nohalf nonames noheader
di in green "variance matrix of the latent traits: " _c
di
matrix list `sigma',noblank nohalf nonames noheader
if "`data'"=="" {
clear
local temp=2^(`nbitems'*2)
qui range x1 0 `=`temp'-1' `temp'
qui g t=x1
qui g x2=x1
qui g x=x2
loc i=1
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui g item`i'=mod(t,2^`i')==2^`=`i'-1'
qui replace t=t-item`i'*2^`=`i'-1'
qui count if t>0
loc z=r(N)
loc i=`i'+1
}
}
drop t
*edit
if "`fast'"=="" {
qui gen proba=.
*qui gen proba2=.
forvalues i=1/`temp' {
local int1=1
local int2=1
forvalues j=1/`nbitems' {
qui su item`j' in `i'
local rep=r(mean)
local diffic=`diff'[`j',1]
local int1 "`int1'*exp(`rep'*(x1-`diffic'))/(1+exp(x1-`diffic'))"
*di `j'
*di `int1'
}
*qui gausshermite `int1', mu(1) sigma(2) display
* di r(int)
*qui replace proba=r(int) in `i'
forvalues k=`=`nbitems'+1' /`=2*`nbitems'' {
qui su item`k' in `i'
local rep=r(mean)
local diffic=`diff'[`=`k'-`nbitems'',1]
local int2 "`int2'*exp(`rep'*(x2-`diffic'))/(1+exp(x2-`diffic'))"
}
*di `i'
*di "`int1'"
*di "`int2'"
local int "`int1'*`int2'"
qui gausshermite2 `int', mu(`mu') sigma(`sigma') display
qui replace proba=r(int) in `i'
*di proba[`i']
}
}
gen eff=proba
keep item* proba eff
*gen eff2=`n'*proba2
*keep item* proba proba2 eff1 eff2
edit
local p=1/`n'
qui gen eff2=floor(eff/`p')
*list eff2 eff
qui replace eff=eff-eff2*(`p')
qui su eff2
local aff=r(sum)
local unaff=`n'-`aff'
di `aff'
di `unaff'
gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff'
qui drop if eff2==0
gsort item*
*gen res=proba*50
* keep item* proba eff eff2 aff unaff
* Matrice complete qui ne tient pas compte des effectifs dans l'analyse
qui expand eff2
*qui drop proba eff eff2
*keep item* proba eff eff2
*}
forvalues j=1/`nbitems' {
rename item`j' T1reponse`j'
}
forvalues j=`=1+`nbitems''/`=2*`nbitems'' {
rename item`j' T2reponse`=`j'-`nbitems''
}
rename eff2 Eff
keep T1reponse* T2reponse* Eff
gen id=_n
forvalues i=1/`nbitems'{
local list="`list' T@reponse`i'"
}
reshape long `list', i(id) j(temps)
reshape long Treponse, i(id temps) j(item)
forvalues i=1/`nbitems'{
gen item`i'=0
replace item`i'=-1 if item==`i'
}
gen temps1=temps==1
gen temps2=temps==2
*gen W1=0
*gen W2=0
*replace W1=Eff if temps1==1
*replace W2=Eff if temps2==1
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[`i',1] if item==`i'
}
matrix C=cholesky(`sigma')
*constraint define 1 `sigma'[1,1]-C[1,1]^2=0
*constraint define 2 `sigma'[2,2]-C[2,1]^2-C[2,2]^2=0
*constraint define 3 `sigma'[2,1]-C[1,1]*C[2,1]=0
*constraint define 1 id_1:temps1=`=sqrt(`sigma'[1,1])'
*constraint define 2 id_2:temps2=`=sqrt(`sigma'[2,2]-`sigma'[2,1]^2/`sigma'[1,1])'
*constraint define 3 id1_2_1:_cons=`=`sigma'[2,1]/sqrt(`sigma'[1,1])'
*constraint define 1 var(1): =`=`sigma'[1,1]'
*constraint define 2 cov(2,1): =`=`sigma'[1,2]'
*constraint define 3 var(2): =`=`sigma'[2,2]'
constraint define 1 id1_1:temps1=`=C[1,1]'
constraint define 2 id1_2:temps2=`=C[2,2]'
constraint define 3 id1_2_1:_cons=`=C[2,1]'
/*CODE JBH*/
gen Treponse1=Treponse if temps1
replace Treponse1=0 if Treponse1==.
gen Treponse2=Treponse if temps2
replace Treponse2=0 if Treponse2==.
constraint define 1 Treponse1=`=C[1,1]'
constraint define 2 Treponse2=`=C[2,2]'
constraint define 3 _cons=`=C[2,1]'
eq b1:Treponse1
eq b2:Treponse2
/*FIN CODE JBH*/
gllamm Treponse temps1 temps2, offset(offset) i(id) link(logit) nocons fam(bin) nrf(2) constraints(1 2 3) eqs(b1 b2) iterate(20) trace
capture qui use `raschlongitudinalfile',clear
end

View File

@ -0,0 +1,227 @@
program define raschpce,rclass
syntax varlist [if] [in] [, rsm]
preserve
if "`if'"!=""|"`in'"!="" {
di "if:`if' in: `in'"
keep `if' `in'
}
tokenize `varlist'
local nbitems:word count `varlist'
local lines=1
local summ=0
local modamax=0
forvalues i=1/`nbitems' {
qui su ``i''
local moda`i'=r(max)
local lines=`lines'*(`moda`i''+1)
local summ=`summ'+`moda`i''
if `modamax'<`moda`i'' {
local modamax `moda`i''
}
}
local col=1+`nbitems'
*di "matrix table=J(`lines',`col',.)"
*matrix table=J(`lines',`col',.)
local line=1
/*forvalues i=1/`nbitems' {
forvalues j=`=`i'+1'/`nbitems' {
forvalues mi=0/`moda`i'' {
forvalues mj=0/`moda`j'' {
matrix table[`line',`i']=`mi'
matrix table[`line',`j']=`mj'
qui count if ``i''==`mi'&``j''==`mj'
matrix table[`line',`=`nbitems'+1']=r(N)
local ++line
}
}
}
}
*/
local line=1
forvalues i=1/`nbitems' {
forvalues j=`=`i'+1'/`nbitems' {
forvalues mi=0/`moda`i'' {
forvalues mj=0/`moda`j'' {
qui count if ``i''==`mi'&``j''==`mj'
local table_`line'_`=`nbitems'+1'=r(N)
local ++line
}
}
}
}
qui drop _all
set obs `=`line'-1'
local line=1
forvalues i=1/`nbitems' {
qui gen table`i'=.
}
qui gen table`=`nbitems'+1'=.
*set trace on
forvalues i=1/`nbitems' {
forvalues j=`=`i'+1'/`nbitems' {
forvalues mi=0/`moda`i'' {
forvalues mj=0/`moda`j'' {
qui replace table`i'=`mi' in `line'
qui replace table`j'=`mj' in `line'
qui replace table`=`nbitems'+1'=`table_`line'_`=`nbitems'+1'' in `line'
local ++line
}
}
}
}
*qui svmat table
local ti
local vi
forvalues i=1/`nbitems' {
rename table`i' ``i''
}
rename table`=`nbitems'+1' freq
local s="0"
local max=0
forvalues i=1/`nbitems' {
local max=`max'+`moda`i''
local bi`i'm0=0
local s="`s'+vi`i'mi`moda`i''"
forvalues j=`=`i'+1'/`nbitems' {
qui gen ti`i'j`j'=``i''+``j''
qui replace ti`i'j`j'=0 if ti`i'j`j'==.
local ti "`ti' i.ti`i'j`j'"
}
forvalues mi=1/`moda`i'' {
qui gen vi`i'mi`mi'=``i''==`mi'
local vi "`vi' vi`i'mi`mi'"
}
}
local s="(`s')/`max'"
count
if "`rsm'"=="" {
*edit
qui xi:poisson freq `vi' `ti', nocons iterate(30)
local ll=e(ll)
*set trace on
*lincom -(vi1mi1-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15)
*lincom -(vi1mi2-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15-vi1mi1)
*lincom -(vi1mi3-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15-vi1mi2)
*lincom -.5*(vi1mi1-(vi1mi2+vi2mi2+vi3mi2+vi4mi2+vi5mi2+vi6mi2+vi7mi2)/14)-.5*(vi1mi2-(vi1mi2+vi2mi2+vi3mi2+vi4mi2+vi5mi2+vi6mi2+vi7mi2)/14-vi1mi1)
qui matrix b=e(b)
local col=1
forvalues i=1/`nbitems' {
forvalues mi=1/`moda`i'' {
local bi`i'm`mi'=b[1,`col']
local ++col
}
}
*local s=`s'/`max'
*set trace on
forvalues i=1/`nbitems' {
local location`i'="0"
forvalues mi=1/`moda`i'' {
local delta`i'm`mi'=-(`bi`i'm`mi''-`mi'*`s'-`bi`i'm`=`mi'-1'')
if (`mi'==1) {
qui di "-(vi`i'mi`mi'-`s')"
local tdelta`i'_1 "-(vi`i'mi`mi'-`s')"
qui lincom -(vi`i'mi`mi'-`s')
local location`i' "`location`i''-(vi`i'mi`mi'-`s')"
}
else {
/*QUESTION : DOIT-ON MULTIPLIER `s' par `mi'*/
qui di " vi`i'mi`=`mi'-1'-vi`i'mi`mi'+`s'"
local tdelta`i'_`mi' " vi`i'mi`=`mi'-1'-vi`i'mi`mi'+`s'"
qui lincom vi`i'mi`=`mi'-1'-vi`i'mi`mi'+`s'
local location`i' "`location`i''+vi`i'mi`=`mi'-1'-vi`i'mi`mi'+`s'"
}
local delta`i'_`mi'=r(estimate)
local sedelta`i'_`mi'=r(se)
}
qui lincom (`location`i'')/`moda`i''
local delta`i'=r(estimate)
local sedelta`i'=r(se)
}
forvalues i=1/`nbitems' {
forvalues mi=1/`moda`i'' {
di "delta`i'_`mi' : `delta`i'_`mi'' (`sedelta`i'_`mi'')"
}
di "delta`i' : `delta`i'' (`sedelta`i'')"
}
}
else {
qui gen vmi2=vi1mi2+vi2mi2+vi3mi2
drop vi1mi2 vi2mi2 vi3mi2
edit
qui xi:poisson freq vi1mi1 vi2mi1 vi3mi1 vmi2 `ti', nocons
local ll=e(ll)
*set trace on
*lincom -(vi1mi1-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15)
*lincom -(vi1mi2-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15-vi1mi1)
*lincom -(vi1mi3-(vi1mi3+vi2mi3+vi3mi3+vi4mi3+vi5mi3)/15-vi1mi2)
*lincom -.5*(vi1mi1-(vi1mi2+vi2mi2+vi3mi2+vi4mi2+vi5mi2+vi6mi2+vi7mi2)/14)-.5*(vi1mi2-(vi1mi2+vi2mi2+vi3mi2+vi4mi2+vi5mi2+vi6mi2+vi7mi2)/14-vi1mi1)
forvalues i=1/`nbitems' {
local location`i'="0"
forvalues mi=1/`moda`i'' {
* local delta`i'm`mi'=-(`bi`i'm`mi''-`mi'*`s'-`bi`i'm`=`mi'-1'')
if (`mi'==1) {
qui di "-(vi`i'mi1-vi2)"
local tdelta`i'_1 "-(vi`i'mi1-vi2)"
qui lincom -(vi`i'mi1-vi2)
local location`i' "`location`i''-(vi`i'mi1)"
}
else {
/*QUESTION : DOIT-ON MULTIPLIER `s' par `mi'*/
qui di " vi`i'mi`=`mi'-1'"
local tdelta`i'_`mi' " vi`i'mi`=`mi'-1'"
qui lincom vi`i'mi`=`mi'-1'
local location`i' "`location`i''+vi`i'mi`=`mi'-1'"
}
local delta`i'_`mi'=r(estimate)
local sedelta`i'_`mi'=r(se)
}
qui lincom (`location`i'')/`moda`i''
local delta`i'=r(estimate)
local sedelta`i'=r(se)
}
forvalues i=1/`nbitems' {
forvalues mi=1/`moda`i'' {
di "delta`i'_`mi' : `delta`i'_`mi'' (`sedelta`i'_`mi'')"
}
di "delta`i' : `delta`i'' (`sedelta`i'')"
}
}
*set trace on
matrix delta=J(`nbitems',`modamax',.)
matrix sedelta=J(`nbitems',`modamax',.)
forvalues i=1/`nbitems' {
forvalues mi=1/`moda`i'' {
matrix delta[`i',`mi']=`delta`i'_`mi''
matrix sedelta[`i',`mi']=`sedelta`i'_`mi''
}
}
*set trace on
matrix b=delta
matrix list delta
*matrix delta=delta'
*matrix sedelta=sedelta'
return matrix b=delta
return matrix sedelta=sedelta
return scalar ll=`ll'
restore
*set trace on
matrix list b
*pcm item*, fixed(b)
end

View File

@ -0,0 +1,908 @@
*! version 5.12 : Novembre 19, 2021
*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug
* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display
* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design
* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs
* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections
* version 5.8 : July 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : correction of a bug when the variances are different in the 2 groups (transversal)
* version 5.9 : September 26th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : fixed of a bug with the graph option (correlation could be greater than one)
* version 5.10 : July 18th, 2019 (Jean-Benoit Hardouin) : filesave and dirsave options
* version 5.11 : July 24th, 2019 (Jean-Benoit Hardouin) : pcm->pcmold
* version 5.12 : July 24th, 2019 (Myriam Blanchin) : correction of bug (essai.dta)
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* Bastien Perrot, Bastien.perrot@univ-nantes.fr
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org - anaqol@sphere-nantes.fr
*
* Copyright 2010-2014, 2019 Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
*
* 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 raschpower,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1) min(real 0.25) step(real 1) max(real 9) FILESave DIRSave(string) pro]
version 11
if "`pro'"!="" {
di "START"
}
if "`html'" != "" {
set scheme sj
local htmlregion "graphregion(fcolor(white) ifcolor(white))"
di "<!-- SphereCalc start of response -->"
di "<pre>"
}
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`graph'" != "" & "`longitudinal'" != "" {
if `gvar' != -1 & `gcorr' != -1 {
di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
error 198
}
if `gvar' == -1 & `gcorr' == -1 {
di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
error 198
}
}
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
local var0=1
local var1=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
if "`html'" == "" {
di "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*
if "`max'" == "" {
local max = 9 + `step'/2
}
else {
local max = `max' + `step'/2
}*/
forval v = `min'(`step')`max' {
local w = `v'
}
if `w' < `max' {
local max = `max' + `step'
}
if "`longitudinal'"!="" & `gvar'!=-1 {
local max = min(`max',0.99999) /* pour avoir des corr<72>lations < 1 */
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
di
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
di
tempname ddt
matrix `ddt' = `dd''
matrix colnames `ddt'=`modalities'
matrix rownames `ddt'=`items'
if "`html'" != "" {
matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficult<6C>s dans l'autre sens */
}
else {
matrix list `dd',noblank nohalf noheader
}
di
if "`detail'"!="" & "`html'" == ""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append using `save1'
*qui save d:\tmp,replace
bysort group:su lt
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local tmpprob=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
*di "`dixj'% (`tmpprob')" _c
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
*prout
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else { /*if "`method'"!="GH"*/
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local sum=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'% (`sum')" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
qui gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
qui gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
/*
if "`html'" == "" {
qui save "d:\essai.dta", replace
}*/
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
}
tempname b V/*LONGITUDINAL*/
local row = 1
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
*noi pcm item*, `fi' covariates(groupc)
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
*di "jk pcm item*, `fi' covariates(groupc) `fv'"
/********************************ESSAI 23 mai 2014*/
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
qui gen group=0
qui append using `save1'
qui gen groupc=group-0.5
*di "ON A SIMULE"
**********************************FIN ESSAI 23 mai 2014*/
qui pcmold item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{ /*LONGITUDINAL*/
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
if "`html'" == "" {
di
di
}
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local nbw:word count `var'
if `nbw' == 2 { /* variance commune */
local varc = ((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
}
else {
local varc = `var'
}
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`varc'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`varc'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
if "`detail'"!="" {
di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
if "`graph'" != "" {
local x = "`min'(`step')`max'"
matrix res=J(15,5,.)
matrix colnames res= n0 n1 gamma variance power
local l=1
if "`longitudinal'"==""{
forval var = `x' {
qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
if "`filesave'"!="" {
qui local saving "saving(`dirsave'//planif,replace) nodraw"
}
else {
qui local saving
}
twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
}
}
else {
if `gcorr' != -1 {
local l=1
forval var = `x' {
local cov = `gcorr'*`var'
local matv "`var',`cov'" " \ `cov',`var'"
qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
if "`filesave'"!="" {
qui local saving "saving(`dirsave'//planif,replace) nodraw"
}
else {
qui local saving
}
twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
}
}
if `gvar' != -1 {
matrix res=J(9,5,.)
matrix colnames res= n0 n1 gamma corr power
local l=1
forvalues corr = `x' {
local cov = `corr'*`gvar'
local matv "`gvar',`cov'" " \ `cov',`gvar'"
qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation, margin(top)) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
if "`filesave'"!="" {
qui local saving "saving(`dirsave'//planif,replace) nodraw"
}
else {
qui local saving
}
twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step''))
}
}
}
//di in gr "Method: " in ye "`method'"
if "`html'" != "" {
di "</pre>"
}
}
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,78 @@
{smcl}
{* 6february2012}{...}
{hline}
help for {hi:raschpower}{right:Jean-Benoit Hardouin, Myriam Blanchin}
{hline}
{title:Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals}
{p 8 14 2}{cmd:raschpower} [{cmd:,} {cmdab:n0}({it:#}) {cmdab:n1}({it:#})
{cmdab:gamma}({it:#}) {cmdab:var}({it:# [#]}) {cmdab:d:ifficulties}({it:matrix}) {cmdab:m:ethod}({it:method}) {cmdab:det:ail} {cmdab:exp:ectedpower}({it:#})]
{title:Description}
{p 4 8 2}{cmd:raschpower} allows estimating the power of the Wald test comparing the means of two groups of patients in the context of the Rasch model or the partial-credit model. The estimation is based
on the estimation of the variance of the difference of the means based on the Cramer-Rao bound.
{title:Options}
{p 4 8 2}{cmd:n0} and {cmd:n1} indicates the numbers of individuals in the two groups [100 by default].
{p 4 8 2}{cmd:gamma} indicates the group effect (difference between the two means) [0.5 by default].
{p 4 8 2}{cmd:var} is the expected values of the variances of the latent trait (1 by default): if this option contains only one value, variances are considered as equal between the two groups; if this option contains two values, variances are considered as unequal between the two groups.
{p 4 8 2}{cmdab:d:ifficulties} is a matrix containing the item parameters [one row per item, one column per positive modality - (-1.151, -0.987\-0.615, -0.325\-0.184, -0.043\0.246, 0.554\0.782, 1.724) by default].
{p 4 8 2}{cmd:method}({it:method}) indicates the method for constructing data. ({it:method}) may be GH, MEAN, MEAN+GH or POPULATION+GH [default is method(GH) if number of patterns<500, method(MEAN+GH) if 500<=number of patterns<10000,
method(MEAN) if 10000<=number of patterns<1000000, method(POPULATION+GH) otherwise].
{p 8 14 2} {bf:GH}: The probability of all possible response patterns is estimated by Gauss-Hermite quadratures.
{p 8 14 2} {bf:MEAN}: The mean of the latent trait for each group is used instead of Gauss-Hermite quadratures.
{p 8 14 2} {bf:MEAN+GH}: In a first step, the MEAN method is used to determine the most probable patterns. In a second step, the probability of response patterns is estimated by Gauss-Hermite quadratures on the most probable patterns.
{p 8 14 2} {bf:POPULATION+GH}: The most frequent response patterns are selected from a simulated population of 1,000,000 of individuals. The probability of the selected response patterns is estimated by Gauss-Hermite quadratures.
{p 4 8 2}{cmd:detail} allows a comparison with the classical formula (for manifest variable).
{p 4 8 2}{cmd:expectedpower} allows searching for a sample size in order to reach a fixed level of power (the obtained sample sizes take into account the ratio between $n0$ and $n1$).
{title:Example}
{p 4 8 2}{cmd:. raschpower}
{p 4 8 2}{cmd:. raschpower, n0(200) n1(200) gamma(0.4) var(1.3)}
{p 4 8 2}{cmd:. matrix diff=(-1.47\-0.97\-.23\-0.12\0.02\0.1)}{p_end}
{p 4 8 2}{cmd:. raschpower, n0(127) n1(134) gamma(0.23) d(diff) var(2.58)}{p_end}
{p 4 8 2}{cmd:. matrix diff=(-0.328,-0.811,0.329\ 0.556,0.818,1.409\ 1.394,1.049,1.288\ 0.560,0.363,0.950)}{p_end}
{p 4 8 2}{cmd:. raschpower, d(diff) n0(167) n1(205) gamma(0.178) var(0.77) exp(0.8)}{p_end}
{title:References}
{p 4 8 2}Hardouin J.B., Amri S., Feddag M., S<>bille V. (2012) Towards Power And Sample Size Calculations For The Comparison Of Two Groups Of Patients With Item Response Theory Models. Statistics in Medicine, 31(11): 1277-1290.{p_end}
{p 4 8 2}Blanchin M., Hardouin J.B., Guillemin F., Falissard B., S<>bille V. (2013) Power and sample size determination for the group comparison of patient-reported outcomes with Rasch family models. PLoS ONE, 8(2): e57279.{p_end}
{p 4 8 2}Feddag M.L., Blanchin M., Hardouin J.B., S<>bille V. (2014) Power analysis on the time effect for the longitudinal Rasch model. Journal of Applied Measurement: (under press).{p_end}
{p 4 8 2}Guilleux A., Blanchin M., Hardouin J.B., S<>bille V. (2014) Power and sample size determination in the Rasch model: Evaluation of the robustness of a numerical method to non-normality of the latent trait. Plos One, 9(1): e0083652.{p_end}
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
{p 4 8 2}Myriam Blanchin, PhD, research assistant{p_end}
{p 4 8 2}Bastien Perrot, biostatistician{p_end}
{p 4 8 2}EA4275 "Biostatistics, Pharmacoepidemiology 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}Emails:
{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
{p 13 8 2}{browse "mailto:myriam.blanchin@univ-nantes.fr":myriam.blanchin@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,371 @@
*! version 3.3 : October 2nd, 2012
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 3.3 : October 2nd, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2012 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(real 1) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1)]
version 11
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d
if "`difficulties'"=="" {
matrix `d'=[-1.151, -0.987\-0.615, -0.325\-0.184, -0.043\0.246, 0.554\0.782, 1.724]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`=`nbmodat'^`nbitems'*2' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if "`method'"=="" {
if `nbmodat'^`nbitems'*2<1000 {
local method GH
}
else if `nbmodat'^`nbitems'<10000 {
local method MEAN+GH
}
else if `nbmodat'^`nbitems'<1000000 {
local method MEAN
}
else {
local method POPULATION+GH
}
}
di in gr "Method: " in ye "`method'"
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait: " in ye `var'
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
matrix list `dd',noblank nohalf noheader
di in gr "Number of studied response's patterns: " in ye `=`nbmodat'^`nbitems'*2'
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
else {
qui simirt, clear pcm(`difficulties') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui drop lt1
qui contract item* group, freq(freq)
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
qui keep if keep==1
qui count
local tmp=r(N)
di "Number of kept patterns:`tmp'"
local method GH
}
qui gen mean=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean=`n0'*`gamma'/(`n0'+`n1') if group==1
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
local int=1
forvalues j=1/`nbitems' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`d'[`j',1]
local sum "1+exp(x-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`d'[`j',`m']
local sum "`sum'+exp(`m'*x-`diff`m'')"
}
local int "(`int'*exp(`rep'*x-`diff`rep''))/(`sum')"
}
qui su mean in `i'
local mean=r(mean)
qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display
qui replace proba=r(int) in `i'
}
di
}
else {
qui gen proba=1
forvalues i=1/`nbitems' {
local diff0=0
local diff1=`d'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`d'[`i',`m']
qui gen eps`m'=exp(`m'*mean-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
local int=1
forvalues j=1/`nbitems' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`d'[`j',1]
local sum "1+exp(x-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`d'[`j',`m']
local sum "`sum'+exp(`m'*x-`diff`m'')"
}
local int "(`int'*exp(`rep'*x-`diff`rep''))/(`sum')"
}
qui su mean in `i'
local mean=r(mean)
qui gausshermite `int',mu(`mean') sigma(`=sqrt(`var')') display
qui replace proba=r(int) in `i'
}
}
}
qui gen eff=.
forvalues i=0/1 {
qui replace eff=proba*`n`i'' if group==`i'
}
qui replace eff=proba
qui keep item* eff group proba
local p1=1/`n1'
local p0=1/`n0'
qui gen eff2=.
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
qui gen groupc=group-.5
if `nbmodat'==2 {
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
}
constraint 1 _cons=`=ln(`var')'
qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
tempname b V
}
else {
matrix `db'=`db''
*di "qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var')"
qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var')
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
di
di
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local poweruni=1-normal(1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
di in gr "{hline 91}"
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,676 @@
*! version 4 : January 30th, 2013
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2013 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar HTML(string)]
version 11
if "`html'" != "" {
di "<!-- SphereCalc start of response -->"
}
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"!="" & `nbmodat'>2{
di in red "{p}The {hi:longitudinal} option is not available with polytomous items{p_end}"
error 198
exit
}
if "`longitudinal'"==""{
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
}
else{
capture confirm number `var'
if !_rc {
local var=`var'
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
local var=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
matrix `dlong'=`d'
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`var')'{
if "`html'" == ""{
di "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
else {
di "<p>WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. </p> <br />"
}
}
}
else{
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix matvar=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if !_rc & colsof(`matvar')==2 & rowsof(`matvar')==2 & issymmetric(`matvar'){
matrix matvar=`matvar'
}
else{
di in red "{p}The {hi:var} option should contain a symmetric 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
if "`html'" == "" {
di in gr "Method: " in ye "`method'"
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait: " in ye `var'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list matvar
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
}
else {
di "Method: " in ye "`method'" "<br>"
if "`longitudinal'"==""{
di "Number of individuals in the first group: " in ye `n0' "<br>"
di "Number of individuals in the second group: " in ye `n1' "<br>"
di "Group effect: " in ye `gamma' "<br>"
di "Variance of the latent trait: " in ye `var' "<br>"
}
else{
di "Number of individuals at each time: " in ye `n0' "<br>"
di "Time effect: " in ye `gamma' "<br>"
/*@TODO
* di in gr "Variance matrix of the latent trait: " "<br>"
* matrix list matvar
*/
}
di "Number of items: " in ye `nbitems' "<br>"
}
tempname dd
matrix `dd'=`d'
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`modalities'
matrix rownames `dd'=`items'
if "`html'" == "" {
matrix list `dd',noblank nohalf noheader
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
else {
//di in gr "Number of studied response's patterns: " in ye `nbpatmax' "<br>"
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else {
if "`longitudinal'"==""{
qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 {
if "`html'" == "" {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
}
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`var')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(matvar) display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else {
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`var')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) sigma(matvar) display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 {
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
}
constraint 1 _cons=`=ln(`var')'
qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
tempname b V
}
else {
matrix `db'=`db''
qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var')
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
}
else{
forvalues i=1/`nbitems'{
rename item`i' t1item`i'
}
forvalues i=`=`nbitems'+1'/`nbtotitems'{
rename item`i' t2item`=`i'-`nbitems''
}
qui gen i=_n
local list=""
forvalues i=1/`nbitems'{
local list="`list' t@item`i'"
}
qui reshape long `list', i(i) j(temps)
qui reshape long titem, i(i temps) j(item)
qui drop if titem==.
qui gen offset=0
local itemnb=1
forvalues t=1/`nbt'{
forvalues i=1/`nbitems' {
qui replace offset=-`dlong'[`itemnb',1] if item==`i' & temps==`t'
local ++itemnb
}
}
gen t1=temps==1
gen t2=temps==2
matrix C=cholesky(matvar)
constraint define 1 [i1_1]t1=`=C[1,1]'
constraint define 2 [i1_2]t2=`=C[2,2]'
constraint define 3 [i1_2_1]_cons=`=C[2,1]'
eq b1:t1
eq b2:t2
qui gllamm titem t2,i(i) link(logit) nocons fam(bin) nrf(2) eq(b1 b2) constraints(1 2 3) iterate(20) trace offset(offset)
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
if "`html'" == "" {
di
di
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
else {
di "<table id=" _char(34) "raschpowertable" _char(34) "class=" _char(34) "restable" _char(34) ">"
di "<caption></caption>"
di "<thead><tr><th></th><th colspan=2 align=" _char(34) "center" _char(34) ">Estimation with the</th></tr>"
di "<tr><th></th><th>Cramer-Rao bound</th><th>classical formula</th></tr></thead><tbody>"
}
if "`longitudinal'"==""{
if "`gammafixed'"=="" {
if "`html'" == "" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
else {
di "<tr><th>Estimated value of the group effect</th><td align=" _char(34) "center" _char(34) ">" in ye %7.2f `gammaest' "</td></tr>"
}
}
if "`html'" == "" {
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
}
else {
di "<tr><th>Estimation of the s.e. of the group effect</th><td align=" _char(34) "center" _char(34) ">" in ye %7.2f `se' "</td></tr>"
di "<tr><th>Estimation of the variance of the group effect</th><td align=" _char(34) "center" _char(34) ">" in ye %10.4f `=`se'^2' "</td></tr>"
}
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
}
else{
if "`gammafixed'"=="" {
if "`html'" == "" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
else {
di "<tr><th>Estimated value of the time effect</th><td align=" _char(34) "center" _char(34) ">" in ye %7.2f `gammaest' "</td></tr>"
}
}
if "`html'" == "" {
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
}
else {
di "<tr><th>Estimation of the s.e. of the time effect</th><td align=" _char(34) "center" _char(34) ">" in ye %7.2f `se' "</td></tr>"
di "<tr><th>Estimation of the variance of the time effect</th><td align=" _char(34) "center" _char(34) ">" in ye %10.4f `=`se'^2' "</td></tr>"
}
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=matvar[1,1]'-`=matvar[2,1]'))-1.96)
local clnsn=2*(`=matvar[1,1]'-`=matvar[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
}
if "`html'" == "" {
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
}
else {
di "<tr><th>Estimation of the power</th><td align=" _char(34) "center" _char(34) ">" in ye %6.4f `poweruni' "</td><td align=" _char(34) "center" _char(34) ">" in ye %6.4f `clpower' "</td></tr>"
di "<tr><th>Number of patients for a power of" %6.2f `=`poweruni'*100' "%</th><td align=" _char(34) "center" _char(34) ">" in ye `n0' "/" `n1' "</td><td align=" _char(34) "center" _char(34) ">" in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0'' "</td></tr>"
}
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`html'" == "" {
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
}
else {
di "<tr><th>Ratio of the number of patients</th><td colspan=2 align=" _char(34) "center" _char(34) ">" in ye %6.2f `ratio' "</td></tr>"
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
if "`html'" == "" {
di in gr "{hline 91}"
}
else {
di "</tbody><tfoot><tr><td></td><td colspan=2></td></tr></tfoot></table>"
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,582 @@
*! version 5 : October 22th, 2013
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2013 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower5,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar DETail]
version 11
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
}
else{
capture confirm number `var'
if !_rc {
local var=`var'
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
local var=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
matrix `dlong'=`d'
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`var')'{
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
else{
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait: " in ye `var'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
matrix list `dd',noblank nohalf noheader
if "`detail'"!=""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else {
if "`longitudinal'"==""{
qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`var')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else {
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`var')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 {
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
}
constraint 1 _cons=`=ln(`var')'
qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
tempname b V
}
else {
matrix `db'=`db''
qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var')
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
}
else{
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
di
di
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
/* ceci est un commentaire */
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,651 @@
*! version 5.1 : January 21th, 2014
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower51,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar DETail]
version 11
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
matrix list `dd',noblank nohalf noheader
if "`detail'"!=""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mean(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mean(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append usinf `save1'
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else {
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 {
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
}
if `var0'==`var1' {
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
constraint 1 _cons=`=sqrt(`var0')'
qui gllamm rep groupc ,nocons i(i) offset(offset) constraint(1) fam(bin) link(logit) nrf(1) trace
}
else {
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
qui gllamm rep groupc ,nocons i(i) offset(offset) constraint(1 2 3) fam(bin) link(logit) eqs(B0 B1) nrf(2) trace
}
tempname b V
}
else {
matrix `db'=`db''
if `var0'==`var1' {
qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvar(`var0')
}
else {
qui pcm item*, fixed(`db') covariates(groupc) fixedmu fixedvargroupc(`var')
}
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
}
else{
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
di
di
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,907 @@
*! version 5.11 : July 24, 2019
*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug
* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display
* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design
* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs
* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections
* version 5.8 : July 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : correction of a bug when the variances are different in the 2 groups (transversal)
* version 5.9 : September 26th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : fixed of a bug with the graph option (correlation could be greater than one)
* version 5.10 : July 18th, 2019 (Jean-Benoit Hardouin) : filesave and dirsave options
* version 5.10 : July 24th, 2019 (Jean-Benoit Hardouin) : pcm->pcmold
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* Bastien Perrot, Bastien.perrot@univ-nantes.fr
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org - anaqol@sphere-nantes.fr
*
* Copyright 2010-2014, 2019 Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
*
* 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 raschpower,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1) min(real 0.25) step(real 1) max(real 9) FILESave DIRSave(string) pro]
version 11
if "`pro'"!="" {
di "START"
}
if "`html'" != "" {
set scheme sj
local htmlregion "graphregion(fcolor(white) ifcolor(white))"
di "<!-- SphereCalc start of response -->"
di "<pre>"
}
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`graph'" != "" & "`longitudinal'" != "" {
if `gvar' != -1 & `gcorr' != -1 {
di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
error 198
}
if `gvar' == -1 & `gcorr' == -1 {
di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
error 198
}
}
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
local var0=1
local var1=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
if "`html'" == "" {
di "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*
if "`max'" == "" {
local max = 9 + `step'/2
}
else {
local max = `max' + `step'/2
}*/
forval v = `min'(`step')`max' {
local w = `v'
}
if `w' < `max' {
local max = `max' + `step'
}
if "`longitudinal'"!="" & `gvar'!=-1 {
local max = min(`max',0.99999) /* pour avoir des corr<72>lations < 1 */
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
di
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
di
tempname ddt
matrix `ddt' = `dd''
matrix colnames `ddt'=`modalities'
matrix rownames `ddt'=`items'
if "`html'" != "" {
matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficult<6C>s dans l'autre sens */
}
else {
matrix list `dd',noblank nohalf noheader
}
di
if "`detail'"!="" & "`html'" == ""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append using `save1'
*qui save d:\tmp,replace
bysort group:su lt
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local tmpprob=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
*di "`dixj'% (`tmpprob')" _c
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
*prout
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else { /*if "`method'"!="GH"*/
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local sum=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'% (`sum')" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
qui gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
qui gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
if "`html'" == "" {
qui save "d:\essai.dta", replace
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
}
tempname b V/*LONGITUDINAL*/
local row = 1
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
*noi pcm item*, `fi' covariates(groupc)
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
*di "jk pcm item*, `fi' covariates(groupc) `fv'"
/********************************ESSAI 23 mai 2014*/
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
qui gen group=0
qui append using `save1'
qui gen groupc=group-0.5
*di "ON A SIMULE"
**********************************FIN ESSAI 23 mai 2014*/
qui pcmold item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{ /*LONGITUDINAL*/
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
if "`html'" == "" {
di
di
}
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local nbw:word count `var'
if `nbw' == 2 { /* variance commune */
local varc = ((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
}
else {
local varc = `var'
}
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`varc'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`varc'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
if "`detail'"!="" {
di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
if "`graph'" != "" {
local x = "`min'(`step')`max'"
matrix res=J(15,5,.)
matrix colnames res= n0 n1 gamma variance power
local l=1
if "`longitudinal'"==""{
forval var = `x' {
qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
if "`filesave'"!="" {
qui local saving "saving(`dirsave'//planif,replace) nodraw"
}
else {
qui local saving
}
twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
}
}
else {
if `gcorr' != -1 {
local l=1
forval var = `x' {
local cov = `gcorr'*`var'
local matv "`var',`cov'" " \ `cov',`var'"
qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
if "`filesave'"!="" {
qui local saving "saving(`dirsave'//planif,replace) nodraw"
}
else {
qui local saving
}
twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
}
}
if `gvar' != -1 {
matrix res=J(9,5,.)
matrix colnames res= n0 n1 gamma corr power
local l=1
forvalues corr = `x' {
local cov = `corr'*`gvar'
local matv "`gvar',`cov'" " \ `cov',`gvar'"
qui raschpower, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation, margin(top)) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
if "`filesave'"!="" {
qui local saving "saving(`dirsave'//planif,replace) nodraw"
}
else {
qui local saving
}
twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step''))
}
}
}
//di in gr "Method: " in ye "`method'"
if "`html'" != "" {
di "</pre>"
}
}
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,692 @@
*! version 5.2 : January 22th, 2014
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower52,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail]
version 11
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}on
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
matrix list `dd',noblank nohalf noheader
if "`detail'"!=""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mean(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mean(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append usinf `save1'
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else {
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace
}
tempname b V/*LONGITUDINAL*/
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
*di "pcm item*, `fi' covariates(groupc) `fv'"
qui pcm item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
di
di
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,695 @@
*! version 5.3 : January 29th, 2014
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower53,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail]
version 11
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
local var0=1
local var1=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
matrix list `dd',noblank nohalf noheader
if "`detail'"!=""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append using `save1'
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else {
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
}
tempname b V/*LONGITUDINAL*/
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
di "pcm item*, `fi' covariates(groupc) `fv'"
noi pcm item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
di
di
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,820 @@
*! version 5.4 : March 28th, 2014
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2th, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug
* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower54,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1)]
version 11
if "`html'" != "" {
di "<!-- SphereCalc start of response -->"
di "<pre>"
}
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`graph'" != "" {
if `gvar' != -1 & `gcorr' != -1 {
di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
error 198
}
if `gvar' == -1 & `gcorr' == -1 {
di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
error 198
}
}
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
local var0=1
local var1=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
if "`html'" == "" {
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
di
tempname ddt
matrix `ddt' = `dd''
matrix colnames `ddt'=`modalities'
matrix rownames `ddt'=`items'
if "`html'" != "" {
matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficult<6C>s dans l'autre sens */
}
else {
matrix list `dd',noblank nohalf noheader
}
di
if "`detail'"!="" & "`html'" == ""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append using `save1'
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else {
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
}
tempname b V/*LONGITUDINAL*/
local row = 1
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
*di "pcm item*, `fi' covariates(groupc) `fv'"
noi pcm item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
if "`html'" == "" {
di
di
}
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
if "`graph'" != "" {
matrix res=J(15,5,.)
matrix colnames res= n0 n1 gamma variance power
local l=1
if "`longitudinal'"==""{
foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
qui raschpower54, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace)
}
}
else {
if `gcorr' != -1 {
local l=1
foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
local cov = `gcorr'*`var'
local matv "`var',`cov'" " \ `cov',`var'"
qui raschpower54, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace)
}
}
if `gvar' != -1 {
matrix res=J(15,5,.)
matrix colnames res= n0 n1 gamma corr power
local l=1
forvalues corr = 0.1(0.1)0.9 {
local cov = `corr'*`gvar'
local matv "`gvar',`cov'" " \ `cov',`gvar'"
qui raschpower54, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.4 0.7 0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace)
}
}
}
//di in gr "Method: " in ye "`method'"
if "`html'" != "" {
di "</pre>"
}
}
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,822 @@
*! version 5.5 : April 9th, 2014
*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : inequal variance between groups
* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug
* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display
* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower55,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1)]
version 11
if "`html'" != "" {
di "<!-- SphereCalc start of response -->"
di "<pre>"
}
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`graph'" != "" & "`longitudinal'" != "" {
if `gvar' != -1 & `gcorr' != -1 {
di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
error 198
}
if `gvar' == -1 & `gcorr' == -1 {
di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
error 198
}
}
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
local var0=1
local var1=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
if "`html'" == "" {
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
di
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
di
tempname ddt
matrix `ddt' = `dd''
matrix colnames `ddt'=`modalities'
matrix rownames `ddt'=`items'
if "`html'" != "" {
matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficult<6C>s dans l'autre sens */
}
else {
matrix list `dd',noblank nohalf noheader
}
di
if "`detail'"!="" & "`html'" == ""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append using `save1'
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else {
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
}
tempname b V/*LONGITUDINAL*/
local row = 1
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
*di "pcm item*, `fi' covariates(groupc) `fv'"
noi pcm item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
if "`html'" == "" {
di
di
}
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
if "`graph'" != "" {
matrix res=J(15,5,.)
matrix colnames res= n0 n1 gamma variance power
local l=1
if "`longitudinal'"==""{
foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace)
}
}
else {
if `gcorr' != -1 {
local l=1
foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
local cov = `gcorr'*`var'
local matv "`var',`cov'" " \ `cov',`var'"
qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace)
}
}
if `gvar' != -1 {
matrix res=J(9,5,.)
matrix colnames res= n0 n1 gamma corr power
local l=1
forvalues corr = 0.1(0.1)0.9 {
local cov = `corr'*`gvar'
local matv "`gvar',`cov'" " \ `cov',`gvar'"
qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace)
}
}
}
//di in gr "Method: " in ye "`method'"
if "`html'" != "" {
di "</pre>"
}
}
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,852 @@
*! version 5.7 : June 21th, 2014
*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug
* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display
* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design
* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs
* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchi n, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower56,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1)]
version 11
if "`html'" != "" {
di "<!-- SphereCalc start of response -->"
di "<pre>"
}
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`graph'" != "" & "`longitudinal'" != "" {
if `gvar' != -1 & `gcorr' != -1 {
di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
error 198
}
if `gvar' == -1 & `gcorr' == -1 {
di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
error 198
}
}
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
local var0=1
local var1=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
if "`html'" == "" {
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
di
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
di
tempname ddt
matrix `ddt' = `dd''
matrix colnames `ddt'=`modalities'
matrix rownames `ddt'=`items'
if "`html'" != "" {
matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficult<6C>s dans l'autre sens */
}
else {
matrix list `dd',noblank nohalf noheader
}
di
if "`detail'"!="" & "`html'" == ""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append using `save1'
*qui save d:\tmp,replace
bysort group:su lt
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local tmpprob=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
*di "`dixj'% (`tmpprob')" _c
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
*prout
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else { /*if "`method'"!="GH"*/
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local sum=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'% (`sum')" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
qui gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
qui gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
qui save "d:\essai.dta", replace
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
}
tempname b V/*LONGITUDINAL*/
local row = 1
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
*noi pcm item*, `fi' covariates(groupc)
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
*di "jk pcm item*, `fi' covariates(groupc) `fv'"
/********************************ESSAI 23 mai 2014*/
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
qui gen group=0
qui append using `save1'
qui gen groupc=group-0.5
*di "ON A SIMULE"
**********************************FIN ESSAI 23 mai 2014*/
qui pcm item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{ /*LONGITUDINAL*/
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
if "`html'" == "" {
di
di
}
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`var'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`var'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
if "`detail'"!="" {
di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
if "`graph'" != "" {
matrix res=J(15,5,.)
matrix colnames res= n0 n1 gamma variance power
local l=1
if "`longitudinal'"==""{
foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace)
}
}
else {
if `gcorr' != -1 {
local l=1
foreach var in 0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 {
local cov = `gcorr'*`var'
local matv "`var',`cov'" " \ `cov',`var'"
qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(0.25 0.5 0.75 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9) xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace)
}
}
if `gvar' != -1 {
matrix res=J(9,5,.)
matrix colnames res= n0 n1 gamma corr power
local l=1
forvalues corr = 0.1(0.1)0.9 {
local cov = `corr'*`gvar'
local matv "`gvar',`cov'" " \ `cov',`gvar'"
qui raschpower55, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(0.1[0.1]0.9) xtitle(Correlation) ytitle(Power) name(planif_graph,replace)
}
}
}
//di in gr "Method: " in ye "`method'"
if "`html'" != "" {
di "</pre>"
}
}
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,878 @@
*! version 5.8 : July 9th, 2014
*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug
* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display
* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design
* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs
* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections
* version 5.8 : July 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : correction of a bug when the variances are different in the 2 groups (transversal)
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchi n, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower58,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1) min(real 0.25) step(real 1) max(real 9)]
version 11
if "`html'" != "" {
di "<!-- SphereCalc start of response -->"
di "<pre>"
}
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`graph'" != "" & "`longitudinal'" != "" {
if `gvar' != -1 & `gcorr' != -1 {
di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
error 198
}
if `gvar' == -1 & `gcorr' == -1 {
di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
error 198
}
}
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
local var0=1
local var1=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
if "`html'" == "" {
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*
if "`max'" == "" {
local max = 9 + `step'/2
}
else {
local max = `max' + `step'/2
}*/
forval v = `min'(`step')`max' {
local w = `v'
}
if `w' < `max' {
local max = `max' + `step'
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
di
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
di
tempname ddt
matrix `ddt' = `dd''
matrix colnames `ddt'=`modalities'
matrix rownames `ddt'=`items'
if "`html'" != "" {
matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficult<6C>s dans l'autre sens */
}
else {
matrix list `dd',noblank nohalf noheader
}
di
if "`detail'"!="" & "`html'" == ""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append using `save1'
*qui save d:\tmp,replace
bysort group:su lt
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local tmpprob=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
*di "`dixj'% (`tmpprob')" _c
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
*prout
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else { /*if "`method'"!="GH"*/
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local sum=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'% (`sum')" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
qui gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
qui gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
if "`html'" == "" {
qui save "d:\essai.dta", replace
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
}
tempname b V/*LONGITUDINAL*/
local row = 1
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
*noi pcm item*, `fi' covariates(groupc)
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
*di "jk pcm item*, `fi' covariates(groupc) `fv'"
/********************************ESSAI 23 mai 2014*/
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
qui gen group=0
qui append using `save1'
qui gen groupc=group-0.5
*di "ON A SIMULE"
**********************************FIN ESSAI 23 mai 2014*/
qui pcm item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{ /*LONGITUDINAL*/
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
if "`html'" == "" {
di
di
}
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local nbw:word count `var'
if `nbw' == 2 { /* variance commune */
local varc = ((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
}
else {
local varc = `var'
}
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`varc'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`varc'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
if "`detail'"!="" {
di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
if "`graph'" != "" {
local x = "`min'(`step')`max'"
matrix res=J(15,5,.)
matrix colnames res= n0 n1 gamma variance power
local l=1
if "`longitudinal'"==""{
forval var = `x' {
qui raschpower58, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace)
}
}
else {
if `gcorr' != -1 {
local l=1
forval var = `x' {
local cov = `gcorr'*`var'
local matv "`var',`cov'" " \ `cov',`var'"
qui raschpower58, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable) ytitle(Power) name(planif_graph,replace)
}
}
if `gvar' != -1 {
matrix res=J(9,5,.)
matrix colnames res= n0 n1 gamma corr power
local l=1
forvalues corr = `x' {
local cov = `corr'*`gvar'
local matv "`gvar',`cov'" " \ `cov',`gvar'"
qui raschpower58, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace)
}
}
}
//di in gr "Method: " in ye "`method'"
if "`html'" != "" {
di "</pre>"
}
}
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,884 @@
*! version 5.9 : September 26th, 2014
*! Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot
************************************************************************************************************
* raschpower: Estimation of the power of the Wald test in order to compare the means of the latent trait in two groups of individuals
*
* Version 1 : January 25th, 2010 (Jean-Benoit Hardouin)
* Version 1.1 : January 26th, 2010 (Jean-Benoit Hardouin)
* Version 1.2 : November 1st, 2010 (Jean-Benoit Hardouin)
* version 1.3 : May 2nd, 2011 (Jean-Benoit Hardouin)
* version 1.4 : July 7th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 1.5 : July 11th, 2011 (Jean-Benoit Hardouin) : minor corrections
* version 2 : August 30th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : corrections
* version 3 : October 18th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to the PCM, -method- option, -nbpatterns- options, changes in the presentation of the results
* version 3.1 : October 25th, 2011 (Jean-Benoit Hardouin, Myriam Blanchin) : POPULATION+GH method
* version 3.2 : February 6th, 2012 (Jean-Benoit Hardouin, Myriam Blanchin) : minor corrections
* version 4 : January 30th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design
* version 4.1 : June 3rd, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : detail option
* version 5 : October 22th, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) : Extension to longitudinal design with polytomous items
* version 5.1 : January 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.2 : January 22th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : unequal variance between groups
* version 5.3 : January 29th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin) : correction of a bug
* version 5.4 : April 4th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : HTML option, graph option, minor corrections for results display
* version 5.5 : April 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : graph option for longitudinal design
* version 5.6 : April 10th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : corrections of bugs
* version 5.7 : June 21th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : minor corrections
* version 5.8 : July 9th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : correction of a bug when the variances are different in the 2 groups (transversal)
* version 5.9 : September 26th, 2014 (Jean-Benoit Hardouin, Myriam Blanchin, Bastien Perrot) : fixed of a bug with the graph option (correlation could be greater than one)
*
* Jean-benoit Hardouin, jean-benoit.hardouin@univ-nantes.fr
* Myriam Blanchin, myriam.blanchin@univ-nantes.fr
* EA 4275 "Biostatistics, Pharmacoepidemiology and Subjectives Measures in Health"
* Faculty of Pharmaceutical Sciences - University of Nantes - France
* http://www.sphere-nantes.org
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2010-2014 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
program define raschpower59,rclass
syntax [varlist] [, n0(int 100) n1(int 100) Gamma(real .5) Difficulties(string) Var(string) Method(string) NBPatterns(int 2) nodata EXPectedpower(real -1) LONGitudinal freevar freeitems DETail HTML(string) graph gvar(real -1) gcorr(real -1) min(real 0.25) step(real 1) max(real 9)]
version 11
if "`html'" != "" {
set scheme sj
local htmlregion "graphregion(fcolor(white) ifcolor(white))"
di "<!-- SphereCalc start of response -->"
di "<pre>"
}
tempfile raschpowerfile
capture qui save "`raschpowerfile'",replace
tempname db d dlong matvar
/*******************************************************************************
DEFINITION DES PARAMETRES
*******************************************************************************/
if "`graph'" != "" & "`longitudinal'" != "" {
if `gvar' != -1 & `gcorr' != -1 {
di in red "You cannot use both {hi:gvar} and {hi:gcorr}"
error 198
}
if `gvar' == -1 & `gcorr' == -1 {
di in red "You must precise values for {hi:gvar} or {hi:gcorr} if you use the {hi:graph} option"
error 198
}
}
if "`difficulties'"=="" {
matrix `d'=[-1\-0.5\0\0.5\1]
}
else {
matrix `d'=`difficulties'
}
local nbitems=rowsof(`d')
local nbmodat=colsof(`d')+1
if "`longitudinal'"==""{ /*CAS TRANSVERSAL*/
local nbt=1
local nbtotitems=`nbitems'
local nbpatmax=2*`nbmodat'^`nbitems'
if "`var'"==""{
local var=1
local var0=1
local var1=1
}
else{
capture confirm number `var'
if !_rc {
local var0=`var'
local var1=`var'
}
else{
local nbw:word count `var'
local grp=1
if `nbw'==2 {
local t1: word 1 of `var'
capture confirm number `t1'
if !_rc {
local t2: word 2 of `var'
capture confirm number `t2'
if !_rc {
local var0=`t1'
local var1=`t2'
local grp=2
}
}
}
if `nbw'!=2|`grp'==1 {
capture confirm matrix `var'
if !_rc & colsof(`matvar')==1 & rowsof(`matvar')==1{
matrix `matvar'=`var'
local var0=`matvar'[1,1]
local var1=`matvar'[1,1]
}
else{
di in red "{p}The {hi:var} option should contain a number or a 1x1 matrix for transversal studies{p_end}"
error 198
exit
}
}
}
}
matrix `dlong'=`d' /*DEMANDER A MYRIAM A QUOI CA SERT CAR ON EST EN TRANSVERSAL*/
local varc=((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
local sumd=0
forvalues numit=1/`nbitems'{
local sumd=`sumd'+`d'[`numit',1]
}
local sumd=`sumd'/`nbitems'
if `=abs(`sumd')'>=`=2*sqrt(`varc')'{
if "`html'" == "" {
di in red "{p}WARNING: It is not recommended to use Raschpower when the gap between the global mean of the latent trait (fixed to 0) and the mean of the item parameters is greater than or equal to 2 standard deviation of the latent trait. {p_end}"
}
}
}
else{ /*CAS LONGITUDINAL*/
local nbt=2
local nbtotitems=2*`nbitems'
local nbpatmax=`nbmodat'^(`nbitems'*2)
local n1=0
local mean1=0
local mean2=`mean1'+`gamma'
if "`var'"==""{
matrix `matvar'=(1,0\0,1)
}
else{
matrix `matvar'=`var'
capture confirm matrix `matvar'
if _rc | colsof(`matvar')!=2 | rowsof(`matvar')!=2{
di in red "{p}The {hi:var} option should contain a 2x2 matrix for longitudinal studies{p_end}"
error 198
exit
}
}
matrix `dlong'=J(`nbtotitems',`=`nbmodat'-1',.)
matrix `dlong'[1,1]=`d'
matrix `dlong'[`=`nbitems'+1',1]=`d'
}
/*
if "`max'" == "" {
local max = 9 + `step'/2
}
else {
local max = `max' + `step'/2
}*/
forval v = `min'(`step')`max' {
local w = `v'
}
if `w' < `max' {
local max = `max' + `step'
}
if "`longitudinal'"!="" & `gvar'!=-1 {
local max = min(`max',0.99999) /* pour avoir des corr<72>lations < 1 */
}
/*******************************************************************************
DEFINITION DE LA METHODE
*******************************************************************************/
if substr("`method'",1,3)=="pop" | substr("`method'",1,3)=="POP"{
local method POPULATION+GH
}
if "`method'"=="MEAN+GH"&`nbpatterns'*(`n1'+`n0')>=`nbpatmax' {
di in gr "The MEAN+GH will be inefficient compared to GH since the maximal number of pattern's responses"
di in gr "is lesser than the number of pattern retained by the MEAN+GH method."
di in gr "The -method- option is replaced by GH."
local method GH
}
else if ("`method'"=="MEAN+GH" | "`method'"=="MEAN") & `nbpatmax'>1000000{
di in red "The number of patterns is too high for the chosen method"
exit
}
else if "`method'"=="" {
if `nbpatmax'<2000 {
local method GH
}
else {
local method POPULATION+GH
}
}
if "`method'"!="MEAN+GH" & "`method'"!="MEAN" & "`method'"!="GH" & "`method'"!="POPULATION+GH"{
di in red "Invalid method name"
exit
}
/*******************************************************************************
AFFICHAGE DES PARAMETRES
*******************************************************************************/
if "`longitudinal'"==""{
di in gr "Number of individuals in the first group: " in ye `n0'
di in gr "Number of individuals in the second group: " in ye `n1'
di in green "Group effect: " in ye `gamma'
di in gr "Variance of the latent trait in the first group: " in ye `var0'
di in gr "Variance of the latent trait in the second group: " in ye `var1'
}
else{
di in gr "Number of individuals at each time: " in ye `n0'
di in green "Time effect: " in ye `gamma'
di in gr "Variance matrix of the latent trait: "
matrix list `matvar',noheader
di
}
di in gr "Number of items: " in ye `nbitems'
di in green "Difficulties parameters of the items: "
tempname dd
matrix `dd'=`d''
local items
forvalues i=1/`nbitems' {
local items "`items' item`i'"
}
local modalities
forvalues i=1/`=`nbmodat'-1' {
local modalities "`modalities' delta_`i'"
}
matrix colnames `dd'=`items'
matrix rownames `dd'=`modalities'
di
tempname ddt
matrix `ddt' = `dd''
matrix colnames `ddt'=`modalities'
matrix rownames `ddt'=`items'
if "`html'" != "" {
matrix list `ddt',noblank nohalf noheader /* affiche la matrice des difficult<6C>s dans l'autre sens */
}
else {
matrix list `dd',noblank nohalf noheader
}
di
if "`detail'"!="" & "`html'" == ""{
di in gr "Method: " in ye "`method'"
di in gr "Number of studied response's patterns: " in ye `nbpatmax'
}
matrix `dd'=`d'
local gamma=`gamma'
local tmp=1
qui matrix `db'=J(`=`nbitems'*(`nbmodat'-1)',1,.)
forvalues j=1/`nbitems' {
forvalues m=1/`=`nbmodat'-1' {
qui matrix `db'[`tmp',1]=`d'[`j',`m']
local ++tmp
}
}
/*******************************************************************************
CREATION DU DATASET ATTENDU
*******************************************************************************/
if "`data'"=="" {
clear
if "`method'"!="POPULATION+GH"{
local temp=`nbmodat'^(`nbtotitems')
qui range x 0 `=`temp'-1' `temp'
qui g t=x
loc i=`nbtotitems'
qui count if t>0
loc z=r(N)
qui while `z'>0 {
qui gen item`=`nbtotitems'-`i'+1'=floor(t/`nbmodat'^`=`i'-1')
qui replace t=mod(t,`nbmodat'^`=`i'-1')
qui count if t>0
loc z=r(N)
loc i=`i'-1
}
drop t
if "`longitudinal'"==""{
qui expand 2
qui gen group=0 in 1/`temp'
qui replace group=1 in `=`temp'+1'/`=2*`temp''
}
}
else { /*METHODE POPULATION (SIMULATION)*/
if "`longitudinal'"==""{
*qui simirt, clear pcm(`d') cov(`var') group(`=`n1'*`gamma'/(`n1'+`n0')') deltagroup(`gamma') nbobs(1000000)
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n1'/(`n1'+`n0')*1000000)')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`=round(`n0'/(`n1'+`n0')*1000000)')
qui gen group=0
qui append using `save1'
*qui save d:\tmp,replace
bysort group:su lt
qui drop lt1
qui contract item* group, freq(freq)
qui count
local patobs=r(N)
if `patobs'>=`=(`n0'+`n1')*`nbpatterns''{
qui gen keep=0
qui gsort +group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
qui gsort -group -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n1''
}
else{
qui gen keep=1
}
}
else{
qui simirt, clear pcm(`dlong') covmat(`matvar') mu(`mean1' `mean2') dim(`nbitems' `nbitems') nbobs(1000000)
forvalues j=1/`nbitems'{
rename itemA`j' item`j'
rename itemB`j' item`=`nbitems'+`j''
}
qui drop lt1 lt2
qui contract item*, freq(freq)
local patobs=r(N)
if `patobs'>=`=`n0'*`nbpatterns''{
qui gen keep=0
qui gsort -freq
qui replace keep=1 in 1/`=`nbpatterns'*`n0''
}
else{
qui gen keep=1
}
}
qui keep if keep==1
qui count
local retain=r(N)
di "Number of kept patterns:`retain'"
local method GH
}
if "`longitudinal'"==""{
qui gen mean1=-`n1'*`gamma'/(`n0'+`n1') if group==0
qui replace mean1=`n0'*`gamma'/(`n0'+`n1') if group==1
qui gen var1=`var0' if group==0
qui replace var1=`var1' if group==1
}
else{
qui gen mean1=`mean1'
qui gen mean2=`mean2'
}
/*CALCUL DES PROBAS PAR PATTERNS DE REPONSE*/
if "`method'"=="GH" {
local temp=`nbmodat'^(`nbtotitems')
local diff0=0
qui gen proba=.
local dixj=10
qui count
local tmp=r(N)
forvalues i=1/`tmp' {
local dix=floor(`tmp'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local tmpprob=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
*di "`dixj'% (`tmpprob')" _c
di "`dixj'%" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
*prout
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display name(x1 x2)
qui replace proba=r(int) in `i'
}
}
di
}
else { /*if "`method'"!="GH"*/
qui gen proba=1
forvalues t=1/`nbt'{
forvalues i=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
local diff0=0
local diff1=`dlong'[`i',1]
qui gen eps0=1
qui gen eps1=exp(mean`t'-`diff1')
qui gen d=eps0+eps1
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`i',`m']
qui gen eps`m'=exp(`m'*mean`t'-`diff`m'')
qui replace d=d+eps`m'
}
local listeps
forvalues m=0/`=`nbmodat'-1' {
qui replace proba=proba*eps`m'/d if item`i'==`m'
local listeps `listeps' eps`m'
}
qui drop `listeps' d
}
}
if "`method'"=="MEAN+GH" {
set tracedepth 1
if "`longitudinal'"==""{
qui gen keep=0
qui gsort -group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n1'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui gsort +group -proba
local min=min(`=`nbmodat'^`nbitems'',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
qui su proba if group==0
local sumproba0=r(sum)*100
qui su proba if group==1
local sumproba1=r(sum)*100
}
else{
qui gen keep=0
qui gsort -proba
local min=min(`nbpatmax',`=`n0'*`nbpatterns'')
qui replace keep=1 in 1/`min'
qui keep if keep==1
}
qui drop keep proba
local diff0=0
qui gen proba=.
qui count
local nnew=r(N)
di in gr "Number of studied response's patterns for the GH step: " in ye `nnew'
if "`longitudinal'"==""{
di in gr "(" in ye %6.2f `sumproba0' in gr "% of the group 0 and " in ye %6.2f `sumproba1' in gr "% of the group 1)"
}
local dixj=10
forvalues i=1/`nnew' {
local dix=floor(`nnew'/10)
if mod(`i',`dix')==0 & "`html'"=="" {
qui su proba
local sum=r(sum)
if "`dixj'"!="10" {
di ".." _c
}
di "`dixj'% (`sum')" _c
local dixj=`dixj'+10
}
forvalues t=1/`nbt'{
local int`t'=1
forvalues j=`=(`t'-1)*`nbitems'+1'/`=`t'*`nbitems'' {
qui su item`j' in `i'
local rep=r(mean)
local diff0=0
local diff1=`dlong'[`j',1]
local sum "1+exp(x`t'-`diff1')"
forvalues m=2/`=`nbmodat'-1' {
local diff`m'=`diff`=`m'-1''+`dlong'[`j',`m']
local sum "`sum'+exp(`m'*x`t'-`diff`m'')"
}
local int`t' "(`int`t''*exp(`rep'*x`t'-`diff`rep''))/(`sum')"
}
}
if "`longitudinal'"==""{
qui su mean1 in `i'
local mean=r(mean)
qui su var1 in `i'
local vart=r(mean)
*di "qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)"
qui gausshermite `int1',mu(`mean') sigma(`=sqrt(`vart')') display name(x1)
qui replace proba=r(int) in `i'
}
else{
local int "`int1'*`int2'"
matrix mean=(`mean1',`mean2')
qui gausshermite `int',mu(mean) var(`matvar') display
qui replace proba=r(int) in `i'
}
}
}
}
qui gen eff=proba
qui gen eff2=.
if "`longitudinal'"==""{
qui keep item* eff* group proba
local p1=1/`n1'
local p0=1/`n0'
qui replace eff2=floor(eff/`p1') if group==1
qui replace eff2=floor(eff/`p0') if group==0
qui replace eff=eff-eff2*(`p1'*group+`p0'*(1-group))
qui su eff2 if group==1
local aff1=r(sum)
qui su eff2 if group==0
local aff0=r(sum)
local unaff1=`n1'-`aff1'
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort + group - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui gsort - group - eff
qui replace eff2=eff2+1 in 1/`unaff1'
qui drop if eff2==0
qui gsort group item*
qui expand eff2
}
else{
qui keep item* eff* proba
local p0=1/`n0'
qui replace eff2=floor(eff/`p0')
qui replace eff=eff-eff2*`p0'
qui su eff2
local aff0=r(sum)
local unaff0=`n0'-`aff0'
qui gen efftmp=eff2
qui gsort - eff
qui replace eff2=eff2+1 in 1/`unaff0'
qui drop if eff2==0
qui gsort item*
qui expand eff2
}
qui drop proba eff eff2
}
if "`html'" == "" {
qui save "d:\essai.dta", replace
}
qui alpha item*
local alpha=r(alpha)
if "`longitudinal'"==""{ /*TRANSVERSAL*/
qui gen groupc=-`n1'/(`n0'+`n1') if group==0
qui replace groupc=`n0'/(`n0'+`n1') if group==1
if `nbmodat'==2 { /*DICHOTOMOUS CASE*/
if "`freeitems'"=="" {
local offset "offset(offset)"
local items
}
else {
local offset
local items "item1-item`nbitems'"
}
qui gen i=_n
tempname diff
matrix `diff'=`dd''
qui reshape long item, i(i)
qui rename item rep
qui rename _j item
qui gen offset=0
forvalues i=1/`nbitems' {
qui replace offset=-`diff'[1,`i'] if item==`i'
qui gen item`i'=item==`i'
qui replace item`i'=-item`i'
}
if `var0'==`var1' { /*EQUAL VARIANCES*/
*constraint 1 _cons=`=ln(`var')'
*qui xtlogit rep groupc ,nocons i(i) offset(offset) constraint(1)
if "`freevar'"=="" {
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) nrf(1) trace iterate(100)
}
else {/*UNEQUAL VARIANCES*/
tempvar G0 G1
qui gen `G0'=group==0
qui gen `G1'=group==1
qui eq B0: `G0'
qui eq B1: `G1'
constraint 1 _cons=0
if "`freevar'"=="" { /*FIXED UNEQUAL VARIANCE*/
constraint 2 `G0'=`=sqrt(`var0')'
constraint 3 `G1'=`=sqrt(`var1')'
constraint 1 _cons=`=sqrt(`var0')'
local constvar "constraint(1 2 3)"
}
else { /*FREE UNEQUAL VARIANCES*/
local constvar "constraint(1)"
}
qui gllamm rep groupc `items',nocons i(i) `offset' `constvar' fam(bin) link(logit) eqs(B0 B1) nrf(2) trace iterate(100)
}
tempname b V/*LONGITUDINAL*/
local row = 1
}
else { /*POLYTOMOUS CASE*/
matrix `db'=`db''
if "`freeitems'"=="" {
local fi "fixed(`db') fixedmu"
local row=1
}
else {
local fi
local row=(`nbmodat'-1)*`nbitems'+1
}
if `var0'==`var1' {
if "`freevar'"=="" {
local fv "fixedvar(`var0')"
}
else {
local fv
*noi pcm item*, `fi' covariates(groupc)
}
}
else {
if "`freevar'"=="" {
local fv "fixedvargroupc(`var')"
}
else {
local fv "vargroupc"
}
}
*di "jk pcm item*, `fi' covariates(groupc) `fv'"
/********************************ESSAI 23 mai 2014*/
qui simirt, clear pcm(`d') cov(`var1') mu(`=`n0'*`gamma'/(`n1'+`n0')') nbobs(`n1')
qui gen group=1
tempfile save1
qui save `save1',replace
qui simirt, clear pcm(`d') cov(`var0') mu(`=-`n1'*`gamma'/(`n1'+`n0')') nbobs(`n0')
qui gen group=0
qui append using `save1'
qui gen groupc=group-0.5
*di "ON A SIMULE"
**********************************FIN ESSAI 23 mai 2014*/
qui pcm item*, `fi' covariates(groupc) `fv'
}
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,`row']
local se=`V'[`row',`row']^.5
}
else{ /*LONGITUDINAL*/
qui raschlong item*, nbt(`nbt') diff(`d') var(`matvar')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local gammaest=`b'[1,1]
local se=`V'[1,1]^.5
local n1=`n0'
}
local poweruni=1-normal(1.96-`gamma'/`se')
if "`html'" == "" {
di
di
}
if "`detail'"!=""{
di in gr "{hline 91}"
di _col(60) "Estimation with the "
di _col(50) "Cramer-Rao bound" _col(75) "classical formula"
di in gr "{hline 91}"
}
if "`longitudinal'"==""{
local power=1-normal(1.96-`gamma'/`se')+normal(-1.96-`gamma'/`se')
local nbw:word count `var'
if `nbw' == 2 { /* variance commune */
local varc = ((`n0'-1)*`var0'+(`n1'-1)*`var1')/(`n0'+`n1'-2)
}
else {
local varc = `var'
}
local clpower=normal(sqrt(`n1'*`gamma'^2/((`n1'/`n0'+1)*`varc'))-1.96)
local clnsn=(`n1'/`n0'+1)/((`n1'/`n0')*(`gamma'/sqrt(`varc'))^2)*(1.96+invnorm(`poweruni'))^2
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the group effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the group effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(59) in ye `n0' "/" `n1' _col(77) in ye %7.2f `clnsn' "/" %7.2f `=`clnsn'*`n1'/`n0''
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
else{
local clpower=normal(sqrt(`n0'*`gamma'^2)/(2*(`=`matvar'[1,1]'-`=`matvar'[2,1]'))-1.96)
local clnsn=2*(`=`matvar'[1,1]'-`=`matvar'[2,1]')*(1.96+invnorm(`poweruni'))^2/(`gamma'^2)
local ratio=(`n0'+`n1')/(`clnsn'*(1+`n1'/`n0'))
if "`detail'"==""{
di in gr "{hline 65}"
di in green "Estimation of the variance of the group effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni'
di in gr "{hline 65}"
}
else{
if "`gammafixed'"=="" {
di in green "Estimated value of the time effect" _col(59) in ye %7.2f `gammaest'
}
di in green "Estimation of the s.e. of the time effect" _col(59) in ye %7.2f `se'
di in green "Estimation of the variance of the time effect" _col(56) in ye %10.4f `=`se'^2'
di in green "Estimation of the power" _col(60) in ye %6.4f `poweruni' _col(86) in ye %6.4f `clpower'
di in green "Number of patients for a power of" %6.2f `=`poweruni'*100' "%" _col(63) in ye `n0' _col(85) in ye %7.2f `clnsn'
di in green "Ratio of the number of patients" in ye %6.2f _col(68)`ratio'
di in gr "{hline 91}"
}
}
if `expectedpower'!=-1 {
qui sampsi `=-`gamma'/2' `=`gamma'/2', sd1(`=sqrt(`var')') sd2(`=sqrt(`var')') alpha(0.05) power(`expectedpower') ratio(`=`n1'/`n0'')
local expn_1=r(N_1)
local expn_2=r(N_2)
local expn2=`expn_1'*`ratio'
di in green "Number of patients for a power of" %6.2f `=`expectedpower'*100' "%" _col(51) in ye %7.2f `expn2' "/" %7.2f `=`expn2'*`n1'/`n0'' _c
if "`detail'"!="" {
di _col(77) in ye %7.2f `expn_1' "/" %7.2f `expn_2'
}
}
return scalar EstGamma=`gammaest'
return scalar CRbound=`=`se'^2'
return scalar CRPower=`poweruni'
return scalar ClPower=`clpower'
return scalar ClSS=`clnsn'
return scalar Ratio=`ratio'
return scalar CronbachAlpha=`alpha'
if "`graph'" != "" {
local x = "`min'(`step')`max'"
matrix res=J(15,5,.)
matrix colnames res= n0 n1 gamma variance power
local l=1
if "`longitudinal'"==""{
forval var = `x' {
qui raschpower59, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var(`var') html(`html')
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step'')) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n0=`n0', n1=`n1', {&gamma}=`gamma'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step''))
}
}
else {
if `gcorr' != -1 {
local l=1
forval var = `x' {
local cov = `gcorr'*`var'
local matv "`var',`cov'" " \ `cov',`var'"
qui raschpower59, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`var',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power variance,sort), title("n=`n0', {&gamma}=`gamma', corr=`gcorr'") ylabel(0(0.2)1) xlabel(`x') xtitle(Variance of the latent variable, margin(top)) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step''))
}
}
if `gvar' != -1 {
matrix res=J(9,5,.)
matrix colnames res= n0 n1 gamma corr power
local l=1
forvalues corr = `x' {
local cov = `corr'*`gvar'
local matv "`gvar',`cov'" " \ `cov',`gvar'"
qui raschpower59, n0(`n0') n1(`n1') gamma(`gamma') difficulties(`d') var("`matv'") html(`html') `longitudinal'
qui matrix res[`l',1]=(`n0', `n1', `gamma',`corr',r(CRPower))
local ++l
}
clear
qui svmat res,names(col)
if "`html'" != "" {
qui local saving "saving(`c(tmpdir)'/`html'_planif_graph,replace) nodraw"
qui graph twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation, margin(top)) ytitle(Power) name(planif_graph,replace) `saving'
qui graph use `c(tmpdir)'/`html'_planif_graph.gph
qui graph export `c(tmpdir)'/`html'_planif_graph.eps, replace
di "<br />"
di "<img src=" _char(34) "/data/`html'_planif_graph.png" _char(34)
di " class=" _char(34) "resgraph" _char(34) " alt=" _char(34) "planif_graph" _char(34) " title= " _char(34) "Power as a function of the variance of the latent variable - click to enlarge" _char(34) " width=" _char(34) "350" _char(34) " height=" _char(34) "240" _char(34) " >"
}
else {
twoway (connected power corr,sort), title("n=`n0', {&gamma}=`gamma', var=`gvar'") ylabel(0(0.2)1) xlabel(`x') xtitle(Correlation) ytitle(Power) name(planif_graph,replace) xscale(range(`min' `=`max'+`step''))
}
}
}
//di in gr "Method: " in ye "`method'"
if "`html'" != "" {
di "</pre>"
}
}
capture qui use `raschpowerfile',clear
end

View File

@ -0,0 +1,235 @@
*! Version 1.2 June 3, 2013
************************************************************************************************************
* Stata program : raschres
* Analysis of the residuals of the Rasch model
* Version 1 : June 16, 2010
* Version 1.1 : July 15, 2011
* Version 1.2 : June 3, 2013 /*formatting outputs*/
*
*
* Jean-benoit Hardouin, phD, Assistant Professor
* EA4275 - SPHERE
* Team of Biostatistics, Pharmacoepidemiology and Subjective Measures in Health Sciences
* University of Nantes - Faculty of Pharmaceutical Sciences
* France
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2010-2013 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 raschres,rclass
syntax varlist [if] [in] , diff(string) theta(varname) [genres(string) genfit(string) vargroup(varname) PCAres DETails]
tempfile saveraschres
if "`if'"!=""|"`in'"!="" {
*keep `if' `in'
}
*qui save `saveraschres',replace
tempname res
qui count
local ntotal=r(N)
tokenize `varlist'
local nbitems: word count `varlist'
qui tempname score lt
qui genscore `varlist',score(`score')
qui gen `lt'=`theta'
forvalues i=1/`nbitems' {
local z2`i'=0
}
forvalues i=1/`nbitems'{
qui tempname p`i' res`i'
qui gen `p`i''=exp(`lt'-`diff'[1,`i'])/(1+exp(`lt'-`diff'[1,`i']))
qui gen `res'`i'=(1-`p`i'')/sqrt(`p`i''*(1-`p`i'')) if ``i''==1
qui replace `res'`i'=(0-`p`i'')/sqrt(`p`i''*(1-`p`i'')) if ``i''==0
}
su
local chi2=0
forvalues i=1/`nbitems' {
qui tempname res2
qui gen `res2'`i'=`res'`i'^2
qui su `res2'`i'
local chi2=`chi2'+`r(sum)'
label variable `res'`i' "``i''"
}
su
tempname cor Ev
matrix `cor'=J(`nbitems',`nbitems',.)
local list
forvalues i=1/`nbitems' {
forvalues j=1/`nbitems' {
qui corr `res'`i' `res'`j'
matrix `cor'[`i',`j']=r(rho)
}
local list "`list' ``i''"
}
matrix colname `cor'=`list'
matrix rowname `cor'=`list'
qui pca `res'*
matrix `Ev'=e(Ev)
tempname lt2 ltcl group df nbmiss rep total
qui egen `nbmiss'=rowmiss(`varlist')
qui gen `rep'=`nbitems'-`nbmiss'
qui gen `lt2'=`lt' if `score'!=0&`score'!=`rep'
if "`vargroup'"=="" {
qui gengroup `lt2', newvar(`group') cont det minsize(33)
}
else {
qui `group'=`vargroup'
}
qui su `group'
local maxgroup=r(max)
if "`details'"!="" {
di "{hline 42}"
di _col(12) "Min" _col(29) "Max"
di "{dup 42:-}"
di "" _col(8) "" _col(14) "Latent" _col(28) "" _col(31) "Latent" _col(53) ""
di "Group" _col(8) "Score" _col(15) "trait" _col(25) "Score" _col(32) "trait" _col(42) "n"
di "{hline 42}"
forvalues i=1/`maxgroup' {
qui count if `group'==`i'
local n`i'=r(N)
qui su `score' if `group'==`i'
local scoremin`i'=r(min)
local scoremax`i'=r(max)
qui su `lt' if `group'==`i'
local ltmin`i'=r(min)
local ltmax`i'=r(max)
di "`i'" _col(9) %4.0f `scoremin`i'' _col(14) %6.3f `ltmin`i'' _col(26) %4.0f `scoremax`i'' _col(31) %6.3f `ltmax`i'' _col(39) %4.0f `n`i''
}
di "{hline 42}"
}
local nj=0
forvalues i=1/`nbitems' {
qui count if ``i''!=.
local nj=`nj'+r(N)
}
qui gen `df'=(`nj'-(`ntotal' + `nbitems' - 1 ))/`nj'*`rep'
qui gen `total' =`score'
local mult=(`nj'-(`ntotal' + `nbitems' - 1 ))/`nj'
forvalues i=1/`nbitems' {
qui count if (`total'!=0&`total'!=`rep')&``i''!=.
local mult`i'=r(N)
local df`i'=`mult'*`mult`i''
tempname res2`i'
qui gen `res2`i''=(`res'`i')^2
qui su `res2`i'' if `total'!=0&`total'!=`rep'
local sumsq`i'=r(sum)
local fit`i'=(`sumsq`i''-`df`i'')/sqrt(2*`df`i'')
}
qui gen `ltcl'=.
forvalues g=1/`maxgroup' {
qui su `lt' if `group'==`g'
local ltgroup`g'=r(mean)
local N`g'=r(N)
qui replace `ltcl'=`ltgroup`g'' if `group'==`g'
}
forvalues i=1/`nbitems' {
local chi`i'=0
forvalues g=1/`maxgroup' {
qui su ``i'' if `group'==`g'
local po`i'_`g'=r(mean)
local pe`i'_`g'=exp(`ltgroup`g''-`diff'[1,`i'])/(1+exp(`ltgroup`g''-`diff'[1,`i']))
local std`i'_`g'=2*`N`g''*(`po`i'_`g''-`pe`i'_`g'')^2/sqrt(.5*(`po`i'_`g''+`pe`i'_`g'')*(1-.5*(`po`i'_`g''+`pe`i'_`g'')))
local chi`i'=`chi`i''+`std`i'_`g''
}
di "chi item ``i'' = `chi`i''"
}
local chisq=0
tempname y2 vy2
qui gen `y2'=0
qui gen `vy2'=0
forvalues i=1/`nbitems' {
qui replace `y2'=`y2'+`res'`i'^2 if ``i''!=.
qui replace `vy2'=`vy2'+2*tanh((`lt2'-`diff'[1,`i'])/2)*sinh(`lt2'-`diff'[1,`i']) if ``i''!=.
tempname y2`i' vy2`i'
qui gen `y2`i''=`res'`i'^2
qui su `y2`i'' if `total'!=0&`total'!=`rep'&``i''!=.
local sumy2`i'=r(sum)
qui tab `ltcl'
qui gen `vy2`i''=2*tanh((`lt2'-`diff'[1,`i'])/2)*sinh(`lt2'-`diff'[1,`i'])
di "item ``i''"
su `vy2`i'' if `total'!=0&`total'!=`rep'&``i''!=.
local sumvy2`i'=r(sum)
local fit`i'=(`sumy2`i''-`df`i'')/sqrt(`sumvy2`i'')
local fit2`i'=`df`i''*(ln(`sumy2`i'')-ln(`df`i''))/sqrt(`sumvy2`i'')
local chisq`i'=0
forvalues g=1/`maxgroup' {
qui su `y2`i'' if `group'==`g'&``i''!=.
local sumy2`i'_g`g'=r(sum)
local n`i'g`g'=r(N)
qui su `vy2`i'' if `group'==`g'&``i''!=.
local sumvy2`i'_g`g'=r(sum)
local fit`i'_g`g'=(`sumy2`i'_g`g''-`n`i'g`g'')/sqrt(`sumvy2`i'_g`g'')
local chisq`i'=`chisq`i''+(`fit`i'_g`g'')^2
}
local chisq=`chisq'+`chisq`i''
/*fit2 est l'<27>quivalent de FitResid et chisq est correct*/
}
local RMSEA=sqrt(`chisq'/((`nbitems'*(`maxgroup'-1)-1)*(`ntotal'-1)))
di in gr "{hline 55}"
di in gr "Items" _col(18) "FitResid" _col(31) "ChiSq" _col(42) "df" _col(55) "p"
di in gr "{hline 55}"
forvalues i=1/`nbitems' {
di in ye abbrev("``i''",18) _col(19) %7.3f `fit2`i'' _col(30) %6.2f `chisq`i'' _col(40) %4.0f `=`maxgroup'-1' _col(50) %6.4f 1-chi2(`=`maxgroup'-1',`chisq`i'')
}
di in gr "{dup 55:-}"
di in ye "Total" _col(30) %6.2f `chisq' _col(40) %4.0f `=(`maxgroup'-1)*`nbitems'' _col(50) %6.4f 1-chi2(`=(`maxgroup'-1)*`nbitems'',`chisq`i'')
di in ye "RMSEA" _col(30) %6.4f `RMSEA'
di in gr "{hline 55}"
di
if "`pcares'"!="" {
di "{hline 36}"
di "Correlation matrix between residuals"
di "{hline 36}"
matrix list `cor',noheader format(%5.3f)
di
di "{hline 28}"
di "Eigenvalues of the residuals"
di "{hline 28}"
matrix rowname `Ev'=Eigenvalues
tempname Evp E
matrix `Evp'=`Ev'/`nbitems'
matrix `E'=`Ev' \ `Evp'
matrix rowname `E'=Eigenvalues Proportion
matrix list `E',noheader format(%5.3f)
}
*use `saveraschres', clear
local dfind=`df'/`ntotal'*`nbitems'
if "`genfit'"!="" {
qui gen `genfit'=`df'*(ln(`y2')-log(`df'))/sqrt(`vy2') `if' `in'
}
if "`genres'"!="" {
forvalues i=1/`nbitems' {
qui gen `genres'`i'=`res'`i' `if' `in'
}
}
end

View File

@ -0,0 +1,54 @@
{smcl}
{* 3june2013}{...}
{hline}
help for {hi:raschres}{right:Jean-Benoit Hardouin}
{hline}
{title:Test of fit of the Rasch model using tests similar to RUMM based on residuals}
{p 8 14 2}{cmd:raschres} {varlist} {cmd:,} {cmdab:diff}({it:vector}) {cmdab:theta}({it:varname}) [ {cmdab:genres}({it:string}) {cmdab:genfit}({it:newvarname})
{cmdab:vargroup}({it:varname}) {cmdab:PCA:res} {cmdab:det:ails}]
{title:Description}
{p 4 8 2}{cmd:raschres} allows estimating similar tests than the RUMM software in order to test the fit of the dataset to a Rasch model, or to evaluate the
unidimensionality of the data using a Principal Components Analysis (PCA) on the residuals. {cmd:raschres} is available only for dichotomous items.
{title:Options}
{p 4 8 2}{cmd:diff} is required and defines a (1xJ) vector of values corresponding to the estimations of the difficulty parameters
{p 4 8 2}{cmd:theta} is required and defines a variable containing the estimated values of the latent trait for each individual of the sample.
{p 4 8 2}{cmd:genres} allows creating new variables containing the residuals (one new variable per item). This option must contain a prefix which will be given to
each new variable.
{p 4 8 2}{cmd:genfit} create a new variable containing a fit index for each individual.
{p 4 8 2}{cmd:vargroup} defines a variable containing the affectation between groups of individuals in order to compute fit statistics.
{p 4 8 2} {cmd:pcares} allows providing a PCA on the residuals.
{p 4 8 2} {cmd:details} allows obtaining more detailed results.
{title:Example}
{p 4 8 2}{cmd:. matrix diff=(-1.47,-0.97,-.23,-0.12,0.02,0.1)}{p_end}
{p 4 8 2}{cmd:. raschres items*, diff(diff) theta(theta)}{p_end}
{p 4 8 2}{cmd:. raschres items*, diff(diff) theta(theta) genfit(fit) genres(res)}{p_end}
{p 4 8 2}{cmd:. raschres items*, diff(diff) theta(theta) PCA det}{p_end}
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
{p 4 8 2}EA4275 "Biostatistics, Pharmacoepidemiology 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}Emails:
{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}

View File

@ -0,0 +1,206 @@
*! version 8.10.1 15july2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Raschtest: Rasch model, fit tests and graphical validation
*
* Historic:
* Version 1 (2003-06-30): Jean-Benoit Hardouin
* Version 2 (2003-07-07): Jean-Benoit Hardouin
* Version 3 (2004-01-02): Jean-Benoit Hardouin
* Version 4 (2004-01-21): Jean-Benoit Hardouin
* Version 5 (2004-01-24): Jean-Benoit Hardouin
* Version 6 (2004-02-05): Jean-Benoit Hardouin
* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
* Version 7 (2005-04-02) : Jean-Benoit Hardouin
* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin
* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin
* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin
* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin
* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
* Version 8.3 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option*/
* Version 8.6 (2012-11-19) : Jean-Benoit Hardouin /*HTML option*/
* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*PNG option*/
* Version 8.10 (2019-06-05) : Jean-Benoit Hardouin /*EXTENSION option*/
* Version 8.10.1 (2019-06-15) : Jean-Benoit Hardouin /*NOSTAND option*/
*
* Required modules :
* raschtestv7 version 8.1 (http://freeirt.free.fr)
* gammasym version 2.2 (http://www.freeirt.org)
* gausshermite version 1 (http://www.freeirt.org)
* geekel2d version 4.3 (http://www.freeirt.org)
* genscore version 1.4 (http://www.freeirt.org)
* ghquadm (findit ghquadm)
* gllamm version 2.3.14 (ssc describe gllamm)
* gllapred version 2.3.7 (ssc describe gllapred)
* elapse (ssc describe elapse)
*
* Jean-benoit Hardouin - University of Nantes - France
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research"
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2003-2012, 2019 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define raschtest,eclass
syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string) EXTension(string) graphclose docx(string) noSTand]
local nbitems:word count `varlist'
if "`method'"=="" {
local method "cml"
}
else {
local method=lower("`method'")
}
if "`test'"=="" {
local test "R"
}
else {
local test=upper("`test'")
}
if "`dirsave'"!="" {
local dirsavev8 "dirsave(`dirsave')"
}
if "`method'"!="" {
local methodv8 "method(`method')"
}
if "`test'"!="" {
local testv8 "test(`test')"
}
if "`group'"!="" {
local groupv8 "group(`group')"
}
if "`genlt'"!="" {
local genltv8 "genlt(`genlt')"
}
if "`genscore'"!="" {
local genscorev8 "genscore(`genscore')"
}
if "`genres'"!="" {
local gensresv8 "genres(`genres')"
}
if "`genfit'"!="" {
local genfitv8 "genfit(`genfit')"
}
if "`comp'"!="" {
local compv8 "comp(`comp')"
}
if "`dif'"!="" {
local difv8 "dif(`dif')"
}
if "`iterate'"!="" {
local iteratev8 "iterate(`iterate')"
}
if "`difficulties'"!="" {
local difficultiesv8 "difficulties(`difficulties')"
}
if "`covariates'"!="" {
local covariatesv8 "covariates(`covariates')"
}
raschtestv7 `varlist' `if' `in' , id(`id') html(`html') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8' `png' extension(`extension') `graphclose' docx(`docx') `stand'
/***********************************************************************************************************
RETURN
************************************************************************************************************/
ereturn clear
if `nbitems'>=3 {
if "`method'"=="cml" {
if "`test'"!="none" {
tempname AndersenZv8
matrix `AndersenZv8'=r(AndersenZ)
ereturn matrix AndersenZ=`AndersenZv8'
}
if "`dif'"!="" {
tempname DIFv8
matrix `DIFv8'=r(DIF)
ereturn matrix DIF=`DIFv8'
}
tempname cllv8
scalar `cllv8'=r(cll)
ereturn scalar cll=`cllv8'
}
if "`test'"!="NONE" {
tempname itemFitv8 globalFitv8
matrix `itemFitv8'=r(itemFit)
matrix `globalFitv8'=r(globalFit)
ereturn matrix itemFit=`itemFitv8'
ereturn matrix globalFit=`globalFitv8'
}
}
if "`method'"!="cml" {
tempname sigmav8 sesigmav8
local `sigmav8'=`r(sigma)'
local `sesigmav8'=`r(sesigma)'
ereturn scalar sigma=``sigmav8''
ereturn scalar sesigma=``sesigmav8''
}
tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
matrix `betav8'=r(beta)
matrix `Varbetav8'=r(Varbeta)
ereturn matrix beta=`betav8'
ereturn matrix Varbeta=`Varbetav8'
matrix `thetav8'=r(theta)
matrix `Varthetav8'=r(Vartheta)
ereturn matrix theta=`thetav8'
ereturn matrix Vartheta=`Varthetav8'
scalar `llv8'=`r(ll)'
scalar `AICv8'=`r(AIC)'
ereturn scalar ll=`llv8'
ereturn scalar AIC=`AICv8'
ereturn scalar Zcomp=r(Zcomp)
ereturn scalar pZcomp=r(pZcomp)
if "`method'"=="mml" {
local psi=r(PSI)
local psiadj=r(PSIadj)
ereturn scalar PSI=`psi'
ereturn scalar PSIadj=`psiadj'
}
if "`covariates'"!="" {
tempname betacovariates Vbetacovariates zcovariates pcovariates
matrix `betacovariates'=r(betacovariates)
matrix `Vbetacovariates'=r(Vbetacovariates)
matrix `zcovariates'=r(zcovariates)
matrix `pcovariates'=r(pcovariates)
ereturn matrix betacovariates=`betacovariates'
ereturn matrix Vbetacovariates=`Vbetacovariates'
ereturn matrix zcovariates=`zcovariates'
ereturn matrix pcovariates=`pcovariates'
}
return clear
end

View File

@ -0,0 +1,206 @@
*! version 8.10.1 15july2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Raschtest: Rasch model, fit tests and graphical validation
*
* Historic:
* Version 1 (2003-06-30): Jean-Benoit Hardouin
* Version 2 (2003-07-07): Jean-Benoit Hardouin
* Version 3 (2004-01-02): Jean-Benoit Hardouin
* Version 4 (2004-01-21): Jean-Benoit Hardouin
* Version 5 (2004-01-24): Jean-Benoit Hardouin
* Version 6 (2004-02-05): Jean-Benoit Hardouin
* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
* Version 7 (2005-04-02) : Jean-Benoit Hardouin
* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin
* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin
* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin
* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin
* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
* Version 8.3 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option*/
* Version 8.6 (2012-11-19) : Jean-Benoit Hardouin /*HTML option*/
* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*PNG option*/
* Version 8.10 (2019-06-05) : Jean-Benoit Hardouin /*EXTENSION option*/
* Version 8.10.1 (2019-06-15) : Jean-Benoit Hardouin /*NOSTAND option*/
*
* Required modules :
* raschtestv7 version 8.1 (http://freeirt.free.fr)
* gammasym version 2.2 (http://www.freeirt.org)
* gausshermite version 1 (http://www.freeirt.org)
* geekel2d version 4.3 (http://www.freeirt.org)
* genscore version 1.4 (http://www.freeirt.org)
* ghquadm (findit ghquadm)
* gllamm version 2.3.14 (ssc describe gllamm)
* gllapred version 2.3.7 (ssc describe gllapred)
* elapse (ssc describe elapse)
*
* Jean-benoit Hardouin - University of Nantes - France
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research"
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2003-2012, 2019 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define raschtest,eclass
syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string) EXTension(string) graphclose docx(string) noSTand]
local nbitems:word count `varlist'
if "`method'"=="" {
local method "cml"
}
else {
local method=lower("`method'")
}
if "`test'"=="" {
local test "R"
}
else {
local test=upper("`test'")
}
if "`dirsave'"!="" {
local dirsavev8 "dirsave(`dirsave')"
}
if "`method'"!="" {
local methodv8 "method(`method')"
}
if "`test'"!="" {
local testv8 "test(`test')"
}
if "`group'"!="" {
local groupv8 "group(`group')"
}
if "`genlt'"!="" {
local genltv8 "genlt(`genlt')"
}
if "`genscore'"!="" {
local genscorev8 "genscore(`genscore')"
}
if "`genres'"!="" {
local gensresv8 "genres(`genres')"
}
if "`genfit'"!="" {
local genfitv8 "genfit(`genfit')"
}
if "`comp'"!="" {
local compv8 "comp(`comp')"
}
if "`dif'"!="" {
local difv8 "dif(`dif')"
}
if "`iterate'"!="" {
local iteratev8 "iterate(`iterate')"
}
if "`difficulties'"!="" {
local difficultiesv8 "difficulties(`difficulties')"
}
if "`covariates'"!="" {
local covariatesv8 "covariates(`covariates')"
}
raschtestv7 `varlist' `if' `in' , id(`id') html(`html') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8' `png' extension(`extension') `graphclose' docx(`docx') `stand'
/***********************************************************************************************************
RETURN
************************************************************************************************************/
ereturn clear
if `nbitems'>=3 {
if "`method'"=="cml" {
if "`test'"!="none" {
tempname AndersenZv8
matrix `AndersenZv8'=r(AndersenZ)
ereturn matrix AndersenZ=`AndersenZv8'
}
if "`dif'"!="" {
tempname DIFv8
matrix `DIFv8'=r(DIF)
ereturn matrix DIF=`DIFv8'
}
tempname cllv8
scalar `cllv8'=r(cll)
ereturn scalar cll=`cllv8'
}
if "`test'"!="NONE" {
tempname itemFitv8 globalFitv8
matrix `itemFitv8'=r(itemFit)
matrix `globalFitv8'=r(globalFit)
ereturn matrix itemFit=`itemFitv8'
ereturn matrix globalFit=`globalFitv8'
}
}
if "`method'"!="cml" {
tempname sigmav8 sesigmav8
local `sigmav8'=`r(sigma)'
local `sesigmav8'=`r(sesigma)'
ereturn scalar sigma=``sigmav8''
ereturn scalar sesigma=``sesigmav8''
}
tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
matrix `betav8'=r(beta)
matrix `Varbetav8'=r(Varbeta)
ereturn matrix beta=`betav8'
ereturn matrix Varbeta=`Varbetav8'
matrix `thetav8'=r(theta)
matrix `Varthetav8'=r(Vartheta)
ereturn matrix theta=`thetav8'
ereturn matrix Vartheta=`Varthetav8'
scalar `llv8'=`r(ll)'
scalar `AICv8'=`r(AIC)'
ereturn scalar ll=`llv8'
ereturn scalar AIC=`AICv8'
ereturn scalar Zcomp=r(Zcomp)
ereturn scalar pZcomp=r(pZcomp)
if "`method'"=="mml" {
local psi=r(PSI)
local psiadj=r(PSIadj)
ereturn scalar PSI=`psi'
ereturn scalar PSIadj=`psiadj'
}
if "`covariates'"!="" {
tempname betacovariates Vbetacovariates zcovariates pcovariates
matrix `betacovariates'=r(betacovariates)
matrix `Vbetacovariates'=r(Vbetacovariates)
matrix `zcovariates'=r(zcovariates)
matrix `pcovariates'=r(pcovariates)
ereturn matrix betacovariates=`betacovariates'
ereturn matrix Vbetacovariates=`Vbetacovariates'
ereturn matrix zcovariates=`zcovariates'
ereturn matrix pcovariates=`pcovariates'
}
return clear
end

View File

@ -0,0 +1 @@
.h raschtestv7

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,222 @@
{smcl}
{* 5june2019}{...}
{hline}
help for {hi:raschtest} and {hi:raschtestv7}{right:Jean-Benoit Hardouin}
{hline}
{title:Estimation of the parameters of a Rasch model, tests and specific graphs}
{p 8 14 2}{cmd:raschtestv7} {it:varlist} [{cmd:if} {it:exp}] [{cmd:in} {it:range}]
, {cmdab:id}({it:varname}) [{cmdab:meth:od}({it:keyword}) {cmdab:nold} {cmdab:iterate}({it:#})
{cmdab:t:est}({it:keyword}) {cmdab:diff:iculties}({it:vector})
{cmdab:mean:diff} {cmdab:d:etails} {cmd:group}({it:numlist}) {cmdab:autog:roup}
{cmdab:cov:ariates}({it:varlist}[,{cmd: ss1 ss3}])
{cmdab:dir:save}({it:directory}) {cmdab:files:save} {cmd:png} {cmdab:pause}
{cmdab:rep:lace} {cmdab:nodraw} {cmdab:icc}
{cmdab:inf:ormation} {cmdab:split:test} {cmdab:fit:graph}
{cmdab:genlt}({it:newvarname}[,{cmdab:rep:lace}]) {cmdab:gensco:re}({it:newvarname})
{cmd:genfit}({it:newvarlist}) {cmd:genres}({it:string})
{cmdab:com:p}({it:varname})
{cmdab:dif}({it:varlist})
{cmdab:tr:ace} {cmdab:time}]
{p 8 14 2}{cmd:raschtest} {it:varlist} [{cmd:if} {it:exp}] [{cmd:in} {it:range}]
[, {it:options_of_raschtestv7} {cmdab:gra:ph}]
{p 8 14 2}{it:varlist} is a list of two existing binary variables or more.
{title:Description}
{p 4 8 2}{cmd:raschtest} estimates the parameters of a Rasch model. The estimation
method can be chosen between conditional maximum likelihood (CML), marginal
maximum likelihood (MML) and generalized estimating equations (GEE). {cmd:raschtest}
offer a set of tests, to valuate the fit of the data to the Rasch model, or detect
non homogeneous items (Andersen Z test, First order test (Q1, R1c, R1m, or Wright
Panchapakesan), U test, Split test) and indexes (OUTFIT and INFIT per items or per
individuals). Several graphical representations can be easily obtained: comparison
of the observed and theorical Item Characteristic Curves (ICC), Map difficulty
parameters/Scores, results of the split tests, and information function (for the scale and by item).
{title:Options}
{p 4 8 2}{cmd:method} specifies the used method to estimate the difficulty
parameter among CML ({cmd:method}({it:cml}) - by default), MML ({cmd:method}({it:mml}))
or GEE ({cmd:method}({it:gee})).
{p 4 8 2}{cmd:nold} avoids the Listwise Deletion of the individuals with missing data.
By default, all the individuals with one or more missing data are omited.
{p 4 8 2}{cmd:iterate} allows defining the maximal number of iterations of the maximisation algorithm.
By default, this number is fixed to 200.
{p 4 8 2}{cmd:test} specifies the tests to use among {cmd:test}({it:R}) (by
default, for the R1c or the R1m test), {cmd:test}({it:WP}) (for the Wright-
Panchapakesan test) and {cmd:test}({it:Q}) (for the Q1 test).
{p 4 8 2}{cmd:difficulties} allows fixing the values of the difficulties parameters of the items.
The vector must be a row vector and must contain as many values as items.
This option is available only with {cmd:method}({it:mml}).
{p 4 8 2}{cmd:meandiff} centers the difficulty parameters (only with
{cmd:method}({it:cml})): by default for the CML estimations, the difficulty
parameter to the last item is fixed to 0. With {cmd:meandiff}, only the
diagonal elements of the covariance matrix of these parameters are estimated.
{p 4 8 2}{cmd:details} displays for each group of scores a table containing the
observed and expected number of positive responses and the contribution of this
group to the global first-order statistic.
{p 4 8 2}{cmd:group} specifies groups of scores, by defining the superior
limits of each group (note that the score "0" and this one corresponding to the
number of items are always isolated).
{p 4 8 2}{cmd:autogroup} automatically creates groups of scores (with at least
30 individuals per group).
{p 4 8 2}{cmd:covariates} allows introducing covariates on the model. The {cmd:ss1} and
{cmd:ss3} options allows computing the type 1 and type 3 sums of squares to explain the
variance of the latent trait by these covariates. This option is available only with {cmd:method}({it:mml}).
{p 4 8 2}{cmd:dirsave} specifies the directory where the graphs will be saved
(by default, the directory defined in c(pwd)).
{p 4 8 2}{cmd:filessave} saves all the graphs in .gph files (by default, the
graphs are not saved).
{p 4 8 2}{cmd:png} saves all the graphs in .png files.
{p 4 8 2}{cmd:pause} allows to made a pause between the displaying of each graph.
{p 4 8 2}{cmd:replace} specifies that the existing graphical files will be
replaced.
{p 4 8 2}{cmd:nodraw} avoids displaying of the graphs.
{p 4 8 2}{cmd:icc} displays, for each item, the observed and expected (under the Rasch
model) ICC in a graph.
{p 4 8 2}{cmd:graph} represents in the same graph the distributions of the
difficulty parameters, this one of the scores, and [with {cmd:method}({it:mml}) or
{cmd:method}({it:gee})] the expected distribution of the latent trait, in
function of the latent trait.
{p 4 8 2}{cmd:information} represents the information function for the set of
the items in function of the latent trait.
{p 4 8 2}{cmd:splittest} represents, for each item, the CML estimations of the
difficulty parameters for the others items in the two sub-samples defined by
the individuals who have positively respond to the splitting item for the first
group, and by the individuals who have negatively respond to the splitting item
for the second one.
{p 4 8 2}{cmd:fitgraph} represents four graphs. The first one concerns the
OUTFIT indexes for each item, the second one, the INFIT indexes for each item,
the third one the OUTFIT indexes for each individual, and the last one the
INFIT indexes for each individual.
{p 4 8 2}{cmd:genlt} creates a new variable containing, for each individual,
the estimated value of the latent trait. The {cmd:replace} option allows replacing
an existing variable.
{p 4 8 2}{cmd:genscore} creates a new variable containing, for each individual,
the value of the score.
{p 4 8 2}{cmd:genres} creates new variables containing, for each individual,
the value of the residuals. This option defines the prefix to these new variables
which will be followed by the name of each item.
{p 4 8 2}{cmd:genfit} creates several new variables. {it:newvarlist}
contains two words. The first one represents "outfit" and the second one "infit".
This option generates two variables with this names for the OUTFIT and INFIT
indexes for each individual, and the variables "outfitXX" (by replacing "outfit"
by the first word) for the contribution of the item XX to the OUTFIT index (Note
that the new variables contain unstandardized OUTFIT and INFIT indices, even
the program displays standardized statistics in the results table and with the
{cmd:fitgraph} option).
{p 4 8 2}{cmd:comp} tests the equality of the means of the latent trait for two
groups of individuals defined by a binary variable (only with {cmd:method}({it:mml})
or {cmd:method}({it:gee})).
{p 4 8 2}{cmd:dif} tests the Differential Item Functioning (DIF) on a list of
variables by likelihood ration tests. For each variable defined in the list,
the items parameters are estimated in each groups defined by this variable,
and the test considers the null assumption: the estimations are the same in each group.
The statistic of the test follows a chi-square distribution under the null assumption.
The variable defined in the {cmd:dif} option must have 10 or less modalities, coded
from 0 or 1 to an integer k<=10. This option is available only with {cmd:method}({it:cml}).
{p 4 8 2}{cmd:trace} displays more outputs during the running of the module.
{p 4 8 2}{cmd:time} displays the number of seconds to run the module.
{title:Outputs}
{p 4 8 2}{cmd:e(N)}: Number of observations
{p 4 8 2}{cmd:e(ll)}: (Marginal) Log-likelihood
{p 4 8 2}{cmd:e(cll)}: Conditional log-likelihood
{p 4 8 2}{cmd:e(AIC)}: Akaike Information Criterion
{p 4 8 2}{cmd:e(PSI)} and {cmd:e(PSIadj)}: Personal Separation Indexes (only for {cmd:meth}({it:mml})
{p 4 8 2}{cmd:e(sigma)}: Estimated standard deviation of the latent trait
{p 4 8 2}{cmd:e(sesigma)}: Standard error of the estimated standard deviation of the latent trait
{p 4 8 2}{cmd:e(beta)}: Estimated difficulty parameters
{p 4 8 2}{cmd:e(Varbeta)}: Covariance matrix of the estimated difficulty parameters
{p 4 8 2}{cmd:e(theta)}: Estimated values for the latent trait for each value of the score
{p 4 8 2}{cmd:e(Varbeta)}: Covariance matrix for the estimated values for the latent trait for each value of the score
{p 4 8 2}{cmd:e(itemFit)}: Statistics of fit for each item (first order statistic, degree of freedom, p-value, OUTFIT index, INFIT index, and (if {cmd:method}({it:cml})) U-test statistic
{p 4 8 2}{cmd:e(globalFit)}: Global first order test (statistic, degrees of freedom, p-value)
{p 4 8 2}{cmd:e(AndersenZ)}: Andersen LR Z test (first order statistic, degree of freedom, p-value) (if {cmd:method}({it:cml}))
{p 4 8 2}{cmd:e(DIF)}: DIF LR Z test (statistic, degree of freedom, p-value for each variable defined in {cmd:dif}) (if {cmd:method}({it:cml}))
{p 4 8 2}{cmd:e(Zcomp)} and {cmd:e(pZcomp)}: Statistics of test and associated p-value for the test of comparison of the two population defined with the {cmd:comp} option.
{p 4 8 2}{cmd:e(betacovariates)}, {cmd:e(Vbetacovariates)}, {cmd:e(zcovariates)} and {cmd:e(pcovariates)}: respectivelly the estimated values of the parameters associated to the covariates, the covariance matrix of the estimations, the statistics of the tests to compare the parameters to 0 and the associated p-values (only with the {cmd:covariates} option)
{title:Examples}
{p 4 8 2}{cmd: . raschtest item1-item9, id(id)} /*estimates the parameters by CML approach*/
{p 4 8 2}{cmd: . raschtest item*, id(id) method(gee) information icc dirsave(c:\graphs) filesnames(graphs)}
/*estimates the parameters by GEE, draw the information graph and the ICCs and
save the graphical representations under gph files*/
{p 4 8 2}{cmd: . raschtest item1 item4 item7 item 18 item23 item35-item39 , id(id) group(2 3 4 5) test(WP) split graph}
/*creates groups of score (1 and 2, 3, 4, 5 and more) to compute the Wright
Panchapakesan tests, computes the split test, and represent the map difficulty
parameters/scores*/
{p 4 8 2}{cmd: . matrix diff=(-1,-.5,0,.5,1)}{p_end}
{p 4 8 2}{cmd: . raschtest item1-item5 , id(id) diff(diff) covariable(group sex age,ss1 ss3) nold}
/*difficulties parameters are fixed, 3 covariables are introduced, no listwise deletion*/
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD-HDR, associate professor{p_end}
{p 4 8 2}INSERM UMR 1246-SPHERE "Methods in Patients Centered Outcomes and Health Research"{p_end}
{p 4 8 2}Nantes University - Faculty of Pharmaceutical Sciences{p_end}
{p 4 8 2}Intitute of Research in Health 2{p_end}
{p 4 8 2}22 boulevard Bénoni-Goullin{p_end}
{p 4 8 2}44200 Nantes - FRANCE{p_end}
{p 4 8 2}Email:
{browse "mailto:jean-benoit.hardouin@univ-nantes.fr":jean-benoit.hardouin@univ-nantes.fr}{p_end}
{p 4 8 2}Websites {browse "http://www.anaqol.org":AnaQol}
{title:Also see}
{p 4 13 2}Online: help for {help xtlogit}, {help clogit} and {help geekel2d} and {help gllamm} if installed.{p_end}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,206 @@
*! version 8.10 5july2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Raschtest: Rasch model, fit tests and graphical validation
*
* Historic:
* Version 1 (2003-06-30): Jean-Benoit Hardouin
* Version 2 (2003-07-07): Jean-Benoit Hardouin
* Version 3 (2004-01-02): Jean-Benoit Hardouin
* Version 4 (2004-01-21): Jean-Benoit Hardouin
* Version 5 (2004-01-24): Jean-Benoit Hardouin
* Version 6 (2004-02-05): Jean-Benoit Hardouin
* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
* Version 7 (2005-04-02) : Jean-Benoit Hardouin
* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin
* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin
* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin
* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin
* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
* Version 8.3 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option*/
* Version 8.6 (2012-11-19) : Jean-Benoit Hardouin /*HTML option*/
* Version 8.9 (2019-06-05) : Jean-Benoit Hardouin /*PNG option*/
* Version 8.10 (2019-06-05) : Jean-Benoit Hardouin /*EXTENSION option*/
*
* Required modules :
* raschtestv7 version 8.1 (http://freeirt.free.fr)
* gammasym version 2.2 (http://www.freeirt.org)
* gausshermite version 1 (http://www.freeirt.org)
* geekel2d version 4.3 (http://www.freeirt.org)
* genscore version 1.4 (http://www.freeirt.org)
* ghquadm (findit ghquadm)
* gllamm version 2.3.14 (ssc describe gllamm)
* gllapred version 2.3.7 (ssc describe gllapred)
* elapse (ssc describe elapse)
*
* Jean-benoit Hardouin - University of Nantes - France
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research"
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2003-2012, 2019 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define raschtest,eclass
syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string) EXTension(string) graphclose docx(string)]
local nbitems:word count `varlist'
if "`method'"=="" {
local method "cml"
}
else {
local method=lower("`method'")
}
if "`test'"=="" {
local test "R"
}
else {
local test=upper("`test'")
}
if "`dirsave'"!="" {
local dirsavev8 "dirsave(`dirsave')"
}
if "`method'"!="" {
local methodv8 "method(`method')"
}
if "`test'"!="" {
local testv8 "test(`test')"
}
if "`group'"!="" {
local groupv8 "group(`group')"
}
if "`genlt'"!="" {
local genltv8 "genlt(`genlt')"
}
if "`genscore'"!="" {
local genscorev8 "genscore(`genscore')"
}
if "`genres'"!="" {
local gensresv8 "genres(`genres')"
}
if "`genfit'"!="" {
local genfitv8 "genfit(`genfit')"
}
if "`comp'"!="" {
local compv8 "comp(`comp')"
}
if "`dif'"!="" {
local difv8 "dif(`dif')"
}
if "`iterate'"!="" {
local iteratev8 "iterate(`iterate')"
}
if "`difficulties'"!="" {
local difficultiesv8 "difficulties(`difficulties')"
}
if "`covariates'"!="" {
local covariatesv8 "covariates(`covariates')"
}
raschtestv7 `varlist' `if' `in' , id(`id') html(`html') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8' `png' extension(`extension') `graphclose' docx(`docx')
/***********************************************************************************************************
RETURN
************************************************************************************************************/
ereturn clear
if `nbitems'>=3 {
if "`method'"=="cml" {
if "`test'"!="none" {
tempname AndersenZv8
matrix `AndersenZv8'=r(AndersenZ)
ereturn matrix AndersenZ=`AndersenZv8'
}
if "`dif'"!="" {
tempname DIFv8
matrix `DIFv8'=r(DIF)
ereturn matrix DIF=`DIFv8'
}
tempname cllv8
scalar `cllv8'=r(cll)
ereturn scalar cll=`cllv8'
}
if "`test'"!="NONE" {
tempname itemFitv8 globalFitv8
matrix `itemFitv8'=r(itemFit)
matrix `globalFitv8'=r(globalFit)
ereturn matrix itemFit=`itemFitv8'
ereturn matrix globalFit=`globalFitv8'
}
}
if "`method'"!="cml" {
tempname sigmav8 sesigmav8
local `sigmav8'=`r(sigma)'
local `sesigmav8'=`r(sesigma)'
ereturn scalar sigma=``sigmav8''
ereturn scalar sesigma=``sesigmav8''
}
tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
matrix `betav8'=r(beta)
matrix `Varbetav8'=r(Varbeta)
ereturn matrix beta=`betav8'
ereturn matrix Varbeta=`Varbetav8'
matrix `thetav8'=r(theta)
matrix `Varthetav8'=r(Vartheta)
ereturn matrix theta=`thetav8'
ereturn matrix Vartheta=`Varthetav8'
scalar `llv8'=`r(ll)'
scalar `AICv8'=`r(AIC)'
ereturn scalar ll=`llv8'
ereturn scalar AIC=`AICv8'
ereturn scalar Zcomp=r(Zcomp)
ereturn scalar pZcomp=r(pZcomp)
if "`method'"=="mml" {
local psi=r(PSI)
local psiadj=r(PSIadj)
ereturn scalar PSI=`psi'
ereturn scalar PSIadj=`psiadj'
}
if "`covariates'"!="" {
tempname betacovariates Vbetacovariates zcovariates pcovariates
matrix `betacovariates'=r(betacovariates)
matrix `Vbetacovariates'=r(Vbetacovariates)
matrix `zcovariates'=r(zcovariates)
matrix `pcovariates'=r(pcovariates)
ereturn matrix betacovariates=`betacovariates'
ereturn matrix Vbetacovariates=`Vbetacovariates'
ereturn matrix zcovariates=`zcovariates'
ereturn matrix pcovariates=`pcovariates'
}
return clear
end

View File

@ -0,0 +1,205 @@
*! version 8.6 19november2012
*! Jean-Benoit Hardouin
************************************************************************************************************
* Raschtest: Rasch model, fit tests and graphical validation
*
* Historic:
* Version 1 (2003-06-30): Jean-Benoit Hardouin
* Version 2 (2003-07-07): Jean-Benoit Hardouin
* Version 3 (2004-01-02): Jean-Benoit Hardouin
* Version 4 (2004-01-21): Jean-Benoit Hardouin
* Version 5 (2004-01-24): Jean-Benoit Hardouin
* Version 6 (2004-02-05): Jean-Benoit Hardouin
* Version 6.1 (2004-03-29): Jean-Benoit Hardouin
* Version 6.2 (2004-04-06): Jean-Benoit Hardouin
* Version 6.3 (2004-07-08) : Jean-Benoit Hardouin
* Version 7 (2005-04-02) : Jean-Benoit Hardouin
* Version 7.2 (2005-05-20) : Jean-Benoit Hardouin
* Version 7.3 (2005-07-02) : Jean-Benoit Hardouin
* Version 7.4 (2006-01-15) : Jean-Benoit Hardouin
* Version 7.5 (2006-04-20) : Jean-Benoit Hardouin
* Version 7.6 (2008-06-20) : Jean-Benoit Hardouin /*nold option*/
* Version 8 (2009-06-20) : Jean-Benoit Hardouin /*DIFFICULTIES and COVARIATES options*/
* Version 8.3 (2010-06-15) : Jean-Benoit Hardouin /*GENRES option*/
* Version 8.6 (2012-11-19) : Jean-Benoit Hardouin /*HTML option*/
*
* Needed modules :
* raschtestv7 version 8.1 (http://freeirt.free.fr)
* gammasym version 2.2 (http://www.freeirt.org)
* gausshermite version 1 (http://www.freeirt.org)
* geekel2d version 4.3 (http://www.freeirt.org)
* genscore version 1.4 (http://www.freeirt.org)
* ghquadm (findit ghquadm)
* gllamm version 2.3.14 (ssc describe gllamm)
* gllapred version 2.3.7 (ssc describe gllapred)
* elapse (ssc describe elapse)
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275 "Biostatistics, Clinical Research and Subjective Measures in Health Sciences"
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
* FreeIRT Project : http://www.freeirt.org
*
* Copyright 2003-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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define raschtest,eclass
syntax varlist(min=1 numeric) [if] [in] , ID(varname) [HTML(string) MEANdiff DIRsave(string) FILESsave nodraw PAUse REPlace ICC INFormation SPLITtests FITgraph Method(string) group(numlist >0 ascen) AUTOGroup Test(string) q2 GENLT(string) GENSCOre(string) GENFIT(string) GRAph COMp(varname) dif(varlist) time TRace Details nold iterate(int 200) DIFFiculties(string) COVariates(string) GENRes(string)]
local nbitems:word count `varlist'
if "`method'"=="" {
local method "cml"
}
else {
local method=lower("`method'")
}
if "`test'"=="" {
local test "R"
}
else {
local test=upper("`test'")
}
if "`dirsave'"!="" {
local dirsavev8 "dirsave(`dirsave')"
}
if "`method'"!="" {
local methodv8 "method(`method')"
}
if "`test'"!="" {
local testv8 "test(`test')"
}
if "`group'"!="" {
local groupv8 "group(`group')"
}
if "`genlt'"!="" {
local genltv8 "genlt(`genlt')"
}
if "`genscore'"!="" {
local genscorev8 "genscore(`genscore')"
}
if "`genres'"!="" {
local gensresv8 "genres(`genres')"
}
if "`genfit'"!="" {
local genfitv8 "genfit(`genfit')"
}
if "`comp'"!="" {
local compv8 "comp(`comp')"
}
if "`dif'"!="" {
local difv8 "dif(`dif')"
}
if "`iterate'"!="" {
local iteratev8 "iterate(`iterate')"
}
if "`difficulties'"!="" {
local difficultiesv8 "difficulties(`difficulties')"
}
if "`covariates'"!="" {
local covariatesv8 "covariates(`covariates')"
}
raschtestv7 `varlist' `if' `in' , id(`id') html(`html') `meandiff' `dirsavev8' `filessave' `nodraw' `pause' `replace' `icc' `information' `splittests' `fitgraph' `methodv8' `groupv8' `autogroup' `testv8' `q2' `genltv8' `genscorev8' `genresv8' `genfitv8' `graph' v8 `compv8' `difv8' `time' `trace' `details' `ld' `iteratev8' `difficultiesv8' `covariatesv8'
/***********************************************************************************************************
RETURN
************************************************************************************************************/
ereturn clear
if `nbitems'>=3 {
if "`method'"=="cml" {
if "`test'"!="none" {
tempname AndersenZv8
matrix `AndersenZv8'=r(AndersenZ)
ereturn matrix AndersenZ=`AndersenZv8'
}
if "`dif'"!="" {
tempname DIFv8
matrix `DIFv8'=r(DIF)
ereturn matrix DIF=`DIFv8'
}
tempname cllv8
scalar `cllv8'=r(cll)
ereturn scalar cll=`cllv8'
}
if "`test'"!="NONE" {
tempname itemFitv8 globalFitv8
matrix `itemFitv8'=r(itemFit)
matrix `globalFitv8'=r(globalFit)
ereturn matrix itemFit=`itemFitv8'
ereturn matrix globalFit=`globalFitv8'
}
}
if "`method'"!="cml" {
tempname sigmav8 sesigmav8
local `sigmav8'=`r(sigma)'
local `sesigmav8'=`r(sesigma)'
ereturn scalar sigma=``sigmav8''
ereturn scalar sesigma=``sesigmav8''
}
tempname betav8 Varbetav8 thetav8 Varthetav8 llv8 AICv8
matrix `betav8'=r(beta)
matrix `Varbetav8'=r(Varbeta)
ereturn matrix beta=`betav8'
ereturn matrix Varbeta=`Varbetav8'
matrix `thetav8'=r(theta)
matrix `Varthetav8'=r(Vartheta)
ereturn matrix theta=`thetav8'
ereturn matrix Vartheta=`Varthetav8'
scalar `llv8'=`r(ll)'
scalar `AICv8'=`r(AIC)'
ereturn scalar ll=`llv8'
ereturn scalar AIC=`AICv8'
ereturn scalar Zcomp=r(Zcomp)
ereturn scalar pZcomp=r(pZcomp)
if "`method'"=="mml" {
local psi=r(PSI)
local psiadj=r(PSIadj)
ereturn scalar PSI=`psi'
ereturn scalar PSIadj=`psiadj'
}
if "`covariates'"!="" {
tempname betacovariates Vbetacovariates zcovariates pcovariates
matrix `betacovariates'=r(betacovariates)
matrix `Vbetacovariates'=r(Vbetacovariates)
matrix `zcovariates'=r(zcovariates)
matrix `pcovariates'=r(pcovariates)
ereturn matrix betacovariates=`betacovariates'
ereturn matrix Vbetacovariates=`Vbetacovariates'
ereturn matrix zcovariates=`zcovariates'
ereturn matrix pcovariates=`pcovariates'
}
return clear
end

View File

@ -0,0 +1,203 @@
capture program drop rel
program rel,rclass
syntax varlist, PARTition(numlist integer >0) [SCOrename(string) Alpha(real 0.7) Delta(real 0.9) h(real 0.3) HJmin(real 0.3)]
local C = 0
foreach z in `partition' {
local C = `C' + `z'
}
local nbvars : word count `varlist'
if `C' != `nbvars' {
di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
exit
}
local P:word count `partition'
if "`scorename'" !="" {
local S:word count `scorename'
if `P'!=`S' {
di in red "The number of score names given is different from the number of dimensions in the partition option"
exit
}
}
di as result "{hline}"
di "{bf:Reliability}"
di as result "{hline}"
di
local y = 1
local nbitems = 0
matrix aa = J(`P',4,.)
foreach z in `partition' {
local nbitems = `nbitems' + `z'
}
local i = 1
foreach x in `varlist' {
local var`i' = "`x'"
local `++i'
}
matrix d = J(`nbitems',2,.)
local i = 1
foreach x in `partition' {
if `i' == 1 local s = `x'
else local s = `s' +`x'
local liste = ""
forvalues w = `y'/`s' {
local liste `liste' `var`w''
}
*qui count if !=.
capture qui alpha `liste', asi item std
local al`i' = r(alpha)
local n`i' = e(N)
capture qui loevh `liste', pairwise
local h`i' = r(loevH)
mat a = r(Obs)
*local n`i' = a[1,1]
matrix c = r(loevHj)
matrix ct = c'
local lister = ""
forvalues w = `y'/`s' {
tempvar z
qui gen `z' = round(`var`w'')
local lister `lister' `z'
}
capture qui delta `lister'
local delt`i' = r(delta)
// on remplit d avec les valeurs de ct
local k = 0
forvalues j = `y'/`s' {
local k = `k'+1
matrix d[`j',1] = ct[`k',1]
matrix d[`j',2] = `i'
}
matrix aa [`i',1] = `al`i''
matrix aa [`i',2] = `delt`i''
matrix aa [`i',3] = `h`i''
local `i++'
local y = `s'+1
}
matrix rownames d = `varlist'
local i = 1
local y = 1
foreach x in `partition' {
if `i' == 1 local s = `x'
else local s = `s' +`x'
matrix C = d[`y'..`s',1.]
local min`i' = C[1,1]
local n : rownames C
tokenize `n'
local t`i' = "`1'"
forvalues j = 1/`x' {
local t = "``j''"
if C[`j',1] <= `min`i'' {
local min`i' = C[`j',1]
local t`i' = "``j''"
local itmin`i' = "``j''"
}
}
*di "`t`i''"
matrix aa [`i',4] = `min`i''
local `i++'
local y = `s'+1
}
matrix colnames aa = "alpha" "delta" "H" "Hj_min"
if "`scorename'"=="" {
local i = 1
local y = 1
local name
local nname
forvalues i = 1/`P' {
local name "Dim`i'"
local nname `nname' `name'
}
local scorename = "`nname'"
}
local maxlen = 0
foreach sco in `scorename' {
local w = length("`sco'")
if `w' > `maxlen' local maxlen = `w'
}
local i = 1
local j = 1
local y = 1
local col = `maxlen'+8
di _col(`col') "{bf:n}" _c
local col = `col'+5
di _col(`col') "{bf:alpha}" _c
local col = `col'+8
di _col(`col') "{bf:delta}" _c
local col = `col'+11
di _col(`col') "{bf:H}" _c
local col = `col'+5
di _col(`col') "{bf:Hj_min}"
*di "{hline 41}"
foreach s in `scorename' {
di in blue "{bf:`s'}" _c
local col = `maxlen'+3
local n : di %6.0f `n`i''
di in blue _col(`col') "{text:`n'}" _c
local col = `col'+10
local a : di %5.2f `al`i''
if `a' < `alpha' {
di _col(`col') "{error:`a'} " _c
}
else di _col(`col') "{text:`a'}" _c
local col = `col'+8
local d : di %5.2f `delt`i''
if `d' < `delta' {
di _col(`col') "{error:`d'} " _c
}
else di _col(`col') "{text:`d'}" _c
local col = `col'+8
local h : di %4.2f `h`i''
if `h' < `h' {
di _col(`col') "{error:`h'} " _c
}
else di _col(`col') "{text:`h'}" _c
local col = `col'+8
local m : di %6.2f `min`i''
if `m' < `hjmin' {
di _col(`col') "{error:`m'} " _c
di "{text:(item `itmin`i'')}" _c
}
else di _col(`col') "{text:`m'}" _c
di
local `++i'
}
end
*rel ioc1-ioc37, partition(4 4 7 3 3 4 7 5) scorename(HA PSE W BCC AC AE LI MOC) a(0.7) d(0.9) h(0.3) hjmin(0.3)
*rel x1-x40, partition(5 5 5 5 5 5 5 5) scorename(HA PSE W BCC AC AE LI MOC) a(0.7) d(0.9) h(0.3) hjmin(0.3)

View File

@ -0,0 +1,275 @@
capture program drop repet
program repet,rclass
syntax varlist [in], t2(varlist) PARTition(numlist integer >0) calcmethod(string) [SCOrename(string) KAPpa ICKAPpa(integer 0)]
preserve
local nbvars : word count `varlist'
if "`in'"!="" {
qui keep `in'
}
if `ickappa' <= 0 {
local ickappa = ""
}
/*
if "`ickappa'" != "" & "`kappa'" == "" {
di "{it:The ickappa option is ignored}"
}
*/
local C = 0
foreach z in `partition' {
local C = `C' + `z'
}
local nbvars : word count `varlist'
if `C' != `nbvars' {
di in red "The sum of the numbers in the partition option is different from the number of variables precised in varlist"
exit
}
/*
qui tab `id', nofreq
local u = r(r)
if `u' != _N {
di in red "The variable `ident' has not unique values"
exit
}
*/
local P:word count `partition'
if "`scorename'" !="" {
local S:word count `scorename'
if `P'!=`S' {
di in red "The number of score names given is different from the number of dimensions in the partition option"
exit
}
}
else {
local name
local nname
forvalues i = 1/`P' {
local name "Dim`i'"
local nname `nname' `name'
}
local scorename = "`nname'"
}
local a:word count `varlist'
local b:word count `t2'
if `a' != `b' di in red "The number of items is not the same in t1 and t2"
/* coupure noms des scores */
/*
local i = 1
foreach s in `scorename' {
local len = length("`s'")
if `len' > 10 {
local c = substr("`s'",1,9)
local d = substr("`s'",-1,1)
local s`i' "`c'" "~" "`d'"
}
else local s`i' = "`s'"
local sc `sc' `s`i''
local `++i'
}
*/
local i = 1
foreach s in `scorename' {
local s`i' = abbrev("`s'",10)
local sc `sc' `s`i''
local `++i'
}
/* coupure noms des items */
/*
local i = 1
foreach s in `varlist' {
local len = length("`s'")
if `len' > 10 {
local c = substr("`s'",1,9)
local var`i' "`c'"
}
else local var`i' = "`s'"
local `++i'
}
*/
local i = 1
foreach v in `varlist' {
local var`i' = abbrev("`v'",10)
local `++i'
}
local maxit = 1
forvalues i=1/`nbvars' {
local len = length("`var`i''")
if `len' > `maxit' local maxit = `len'
}
local decit = `maxit' + 4
local colit = `decit'
di as result "{hline}"
di as result "{bf:Reproducibility}"
di as result "{hline}"
di
foreach sco in `scorename' {
*local t = "`sco'bis"
tempname s
local scorename2 `scorename2' `s'
}
qui calcscore `t2', scorename(`scorename2') partition(`partition') calcmethod(`calcmethod')
local i = 1
foreach var in `varlist' {
tokenize `t2'
qui kap `var' ``i''
local k`i' = r(kappa)
if "`ickappa'" != "" {
qui kapci `var' ``i'', reps(`ickappa')
local lbk`i' = r(lb_bc)
local ubk`i' = r(ub_bc)
}
local `++i'
}
local i = 1
foreach s in `scorename' {
tokenize `scorename2'
tempname score id temps
qui gen `id' = _n
qui gen `score'_1 = `s'
qui gen `score'_2 = ``i'' if ``i''!=.
qui reshape long `score'_, i(`id') j(`temps')
qui icc `score'_ `id'
local n`i' = r(N_target)
local icc`i' = r(icc_i)
local lb`i' = r(icc_i_lb)
local ub`i' = r(icc_i_ub)
*qui drop `score' `temps' `id'
qui sort `id'
qui duplicates drop `id', force
local `++i'
}
tokenize `sc'
local max = length("dimension")
forvalues j=1/`P' {
local len`j' = length("`s`j''")
if `len`j'' > `max' local max = `len`j''
}
local dec = `max' + 5
local i = 1
local j = 1
local y = 1
di "{bf:Dimension}" _c
di _col(`=`dec'+2') "{bf:n}" _c
local col = `dec'+6
di _col(`col') "{bf:Item}" _c
local col = `col'+`decit'
if "`kappa'" != "" {
di _col(`col') "{bf:Kappa}" _c
local col = `col'+10
if "`ickappa'" != "" {
di _col(`col') "{bf:95% CI for Kappa}" _c
local col = `col'+20
}
}
di _col(`=`col'+2') "{bf:ICC}" _c
local col = `col'+9
di _col(`col') "{bf:95% CI for ICC}"
local zz = 0
foreach var in `varlist' {
qui levelsof `var', local(levels)
local z : word count `levels'
if `z' > 2 local zz = 1
}
if "`kappa'" != "" & "`ickappa'" != "" & `zz' == 1 {
local col = `dec'+`decit'+16
di _col(`col') "{bf:(bootstrapped)}"
}
if "`ickappa'" != "" local h = `dec'+6+`decit'+10+8+21+12+1
else if "`kappa'" != "" local h = `dec'+6+`decit'+10+8+21+12-20
else local h = `dec'+6+`decit'+10+8+21+12-30
di "{hline `h'}"
local i = 1
foreach p in `partition' {
tokenize `sc'
di "{bf:``i''}" _c
di _col(`dec') "{text:`n`i''}" _c
if `j' == 1 local s = `p'
else local s = `s' +`p'
local col = `dec'+6
di _col(`col') "{text:`var`y''}" _c
if "`kappa'" != "" {
local k : di %5.2f `k`y''
local col = `col'+`decit'
di _col(`col') "{text:`k'}" _c
if "`ickappa'" != "" {
local lbk : di %5.2f `lbk`i''
local ubk : di %5.2f `ubk`i''
local col = `col'+11
di _col(`col') "{text:[`lbk' ; `ubk']}" _c
local col = `decit'+50
}
else local col = `decit'+30
}
else local col = `decit'+20
*local col = `decit'+30
local icc : di %5.2f `icc`i''
di _col(`col') "{text:`icc'}" _c
local lb : di %5.2f `lb`i''
local ub : di %5.2f `ub`i''
local col = `col'+8
di _col(`col')"{text:[`lb' ; `ub']}"
local w = `y'+1
forvalues z = `w'/`s' {
local col = `dec'+6
di _col(`col') "{text:`var`z''}" _c
if "`kappa'" != "" {
local k : di %5.2f `k`z''
local col = `col'+`decit'
di _col(`col') "{text:`k'}" _c
if "`ickappa'" != "" {
local lbk : di %5.2f `lbk`z''
local ubk : di %5.2f `ubk`z''
local col = `col'+11
di _col(`col')"{text:[`lbk' ; `ubk']}"
}
else di
}
else di
}
local `i++'
local `j++'
local y = `s'+1
di
}
end
*repet ioc1-ioc37, t2(ptgi1-peur16) partition(4 4 7 3 3 4 7 5) scorename(HA PSE W BCC AC AE LI MOC) kappa ickappa(20)
*repet sf36_3q_intenses sf36_3q_moderees sf36_3q_soulever sf36_3q_etages sf36_3q_etage sf36_3q_pencher sf36_3q_15km sf36_3q_500m sf36_3q_100m sf36_3q_douche sf36_4q_limite_temps_travail sf36_4q_moins_choses sf36_4q_type_travail sf36_4q_effort , t2(sf36_3q_intenses_v5 sf36_3q_moderees_v5 sf36_3q_soulever_v5 sf36_3q_etages_v5 sf36_3q_etage_v5 sf36_3q_pencher_v5 sf36_3q_15km_v5 sf36_3q_500m_v5 sf36_3q_100m_v5 sf36_3q_douche_v5 sf36_4q_limite_temps_travail_v5 sf36_4q_moins_choses_v5 sf36_4q_type_travail_v5 sf36_4q_effort_v5 ) partition(10 4)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
{smcl}
{* june2020}{...}
{hline}
help for {hi:rosali}{right:Myriam Blanchin - Priscilla Brisson}
{hline}
{title:Detection of response shift at item-level between 2 times of measurement}
{p 4}{cmd:rosali} {it:varlist} [{it:if}] [{it:in}] [, {cmdab:group}({it:string}) {cmdab:nodif} {cmdab:detail}]
{p 4 4 4 140}{it:varlist} contains the list of items: the first part of the list is composed of the items at time 1 and the second part of the items at time 2, in the same order.
{title:Description}
{p 4 12 2 140}{cmd:rosali} performs the {bf:R}esp{bf:O}nse {bf:S}hift {bf:AL}gorithm at {bf:I}tem-level (ROSALI) based on partial credit models
between two times of measurement, time 1 and time 2. Only uniform or non-uniform {bf:r}e{bf:c}alibration can be detected. Response shift detection is performed at item-level assuming all individuals of the sample are affected the same way by default. A dichotomous group variable can be specified with the {cmd:group} option to assess its impact on latent variable, item functioning and response shift. {bf:D}ifferential {bf:I}tem {bf:F}unctionning (DIF) refers to a constant difference of item difficulties between groups over time.
{title:Options}
{p 4 12 2 140}{cmd:group}({it:string}) specifies a binary group variable that can affect item functioning, the estimation of the latent variable means (group effect)
and response shift. Response shift can be common to both groups or differential (occuring in only one group or affecting both groups differentially). By default, response shift detection is performed assuming all individuals are affected in the same way.
{phang}{cmd:nodif} assumes no DIF occurs in the sample and skips DIF detection. Only response shift detection is performed. {it:Use only with group option.}
{phang}{cmd:detail} displays results of each step of ROSALI.
{title:Remarks}
{p 4} {it:Data} must be in wide format, one row per individual.
{p 4} At least two items per time of measurement are required.
{p 4 12 2 140} {cmd:automatic recoding for response categories}
{break} Response categories are automatically recoded to start from 0.
{break} If a response category is not used at one time of measurement, this category is automatically recoded at both times of measurement (for each group if group option).
{break} Rules for automatic recoding:
{break} - 0 response category: merged with response category 1.
{break} - most difficult response category: merged with the previous one.
{break} - other response categories: randomly merged with the next or previous adjacent one.
{title:Outputs}
{p 4 12 2 140}{bf:Matrix:}
{phang}{cmd:r(test_model)}: Result of LRT between models A/B and models 1/2: chi-square statistic, DF and p-value.
{phang}{cmd:r(model_#)}: Item difficulties and latent trait distribution parameters of models #2 or #4 : Estimates, standard errors, 95% confidence interval, chi-square statistics, DF and p-values.
{title:Examples}
{phang}{cmd: . rosali m0gh1 m0gh2 m0gh3 m0gh4 m0gh5 m6gh1 m6gh2 m6gh3 m6gh4 m6gh5, detail }
{phang}{cmd: . rosali it1_t1-it9_t2 , group(cancer_site) }
{title:Reference}
{p} Blanchin, M., Guilleux, A., Hardouin, J.-B., & Sébille, V. (2020). Comparison of structural equation modelling, item response theory and Rasch measurement theory-based methods for response shift detection at item level: A simulation study: Statistical Methods in Medical Research, 19(4), 10151029. https://doi.org/10.1177/0962280219884574
{title:Authors}
{p}Myriam Blanchin, Research engineer, PhD, SPHERE - UMR INSERM U1246, "methodS in Patient-centered outcomes and HEalth ResEarch", University of Nantes, France {browse "mailto:myriam.blanchin@univ-nantes.fr":myriam.blanchin@univ-nantes.fr}
{break}Priscilla Brisson, SPHERE - UMR INSERM U1246, "methodS in Patient-centered outcomes and HEalth ResEarch", University of Nantes, France

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
{smcl}
{* february2019}{...}
{hline}
help for {hi:rosali22}{right:Myriam Blanchin - Priscilla Brisson}
{hline}
{title:Detection of Response Shift at Item-Level between 2 times}
{p 8 14 2}{cmd:rosali22} {it:varlist} [{it:if}] [{it:in}] [, {cmdab:id}({it:string})
{cmdab:moda}({it:# # [#]...}) {cmdab:group}({it:string}) {cmdab:nodif}]
{p 4 4 4 140}{it:varlist} contains items' list : the first half of the items represents the items at time 1 and the second half the items at time 2. (at least 2 items).
{break}{it:Data} : wide format, one line for one patient
{title:Description}
{p 4 12 2 140}{cmd:rosali22}: {bf:R}esp{bf:O}nse {bf:S}hift {bf:AL}gorithm at {bf:I}tem-level (ROSALI),
detection of Response-Shift between two measuring times based on partial credit model.
Only uniform or non-uniform {bf:r}e{bf:c}alibration (RC) can be detected.
A dichotomous group covariate can affect the estimation of the true change(group effect)
and of response shift detected.
Response shift can be common to both groups or differential.
Detection of {bf:d}ifferential {bf:i}tem {bf:f}unctionning (DIF) between two groups with the option group.
{p 4 12 2 140} {ye:PART 1: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN GROUPS AT FIRST TIME OF MEASUREMENT}
{break} {it: Only with group option and without nodif option}
{break} {ye:Model A :} Full model, transversal PCM : estimates of item difficulties free between groups, estimates of latent trait with group effect constrained to 0.
{break} {ye:Model B :} Restricted model, transversal PCM : estimates of item difficulties with constraint of equality between groups, estimates of latent trait including group effect estimate.
{break} .LR test between model A and model B. If this test is significant, algorithm proceeds to step C, otherwise algorithm proceeds to part 2, with constraint of equality between groups of item difficulties.
{break} {ye:Step C :} an iterative step to detect which items have different item difficulties between groups at time 1. At each iteration, equality constraint of item difficulties between groups are relaxed one-by-one
producing multiple models C (starting with model B). For each item, difference in item difficulties between groups is tested, a Bonferroni correction is applied. Item with the most significant test is selected and tested
to determine if the difference in item difficulties is uniform or non-uniform (if number of answer categories is greater to 2). Model C is updated and step C is repeated to identify differences on the remaining items.
{break} .When there is no more item with significant test or only one remaining item to be tested, ROSALI goes on part 2.
{p 4 12 2 140} {ye:PART 2: DETECTION OF DIFFERENCE IN ITEM DIFFICULTIES BETWEEN TIMES (RECALIBRATION)}
{break} For each model, algorithm takes account detection of part 1.
{break} {ye:Model 1 :} Full model, longitudinal PCM : estimates of item difficulties free across times for each group, estimates of latent trait with time effect and interaction time x group constrained to 0.
{break} {ye:Model 2 :} Restricted model, longitudinal PCM : estimates of item difficulties with constraint of equality across times, estimates of latent trait including time effect and interaction time x group estimate.
{break} .LR test between model 1 and model 2. If this test is significant, algorithm proceeds to step 3, otherwise algorithm proceeds to step 4, keeping model 2.
{break} {ye:Step 3 :} an iterative step to detect which items have different item difficulties across times. At each iteration, equality constraint of item difficulties between times are relaxed one-by-one producing multiple
models 3 (starting with model 2). For each item, recalibration is tested, a Bonferroni correction is applied. Item with the most significant test is selected and tested.
{break} .If group option, item is tested to determine if the difference in item difficulties is the same for each group (common RC), in this case, model 3 is updated to take account common recalibration, or different
(differential RC), in this case, recalibration is tested for each group with a Bonferroni correction.
{break} .Type of recalibration : uniform or non-uniform, is finally tested (if number of answer categories is greater to 2). Model 3 is updated and step 3 is repeated to identify differences on the remaining items.
{break} .When there is no more item with significant test or only one remaining item to be tested, ROSALI goes on part 4.
{break} {ye:Model 4 :} Item difficulties and latent trait are estimated with a longitudinal PCM taking account difference or no between groups or times and the type uniform or non-uniform. If interaction time x group is
not significant model 4 is updated with constraint of interaction equal to 0 and we obtained final model.
{p 4 12 2 140} {cmd:automatic coding for answers categories}: Answers at items must be respect 2 conditions. If it is necessary algorithm recodes answers automatically. You can recodes answers before.
{break} - Answers must be ordered and start with 0. If it's necesary, algorithm recodes automatically answers categories to the first answer is 0.
{break} - It's necessary that all answers categories are used at two times of measurement (for each group if option was used).
{break} .If the first answer is not used at one time (or in a group) at least: this answer is merged with next answer.
{break} .If the last answer is not used at one time (or in a group) at least: this answer is merged with the previous answer.
{break} .If an intermediate answer is not used at one time (or in one group) at least: this answer is merged with the next or previous answer of randomly way.
{break} {it: examples :} If there is 4 answers categories, answers lightly are : 0, 1, 2 or 3.
{break} - If answer 0 is not used at one time or for one group, answers 0 and 1 merged (patient who had answered 0 or 1 have now the answer 0, the answer 2 became answer 1 and answer 3 became answer 2)
{break} - If answer 3 is not used at one time or for one group, answers 2 and 3 merged (patient who had answered 2 or 3 have now the answer 2, answers 0 and 1 remain the same)
{break} - If answer 1 (resp. 2) is not used at one time or for one group, randomly answer 1 (resp. 2) merged with answer 0 (resp. 1) or with answer 2 (resp. 3).
{p 4 12 2 140} {cmd:automatic coding for groups}: Rosali needs to have one group 0 and one group 1. If it's necessary Rosali recodes group variable. You can recodes groups before.
{title:Options}
{phang}{cmd:id}({it:string}) specifies the identifiant of individuals. Necessary to validate the data format.
{phang}{cmd:moda}({it:# # [#]...}) specifies the number of answers categories for each item.
{phang}{cmd:group}({it:string}) specifies the binary group variable, allows the detection of differential item functionning (DIF).
{phang}{cmd:nodif} specifies to do only the part 2 of algorithm. No detection of DIF, only detection of response shift for each group. {it:Use only with group option.}
{title:Outputs}
{p 2}{bf:Matrix:}
{phang}{cmd:r(test_model)}: Result of LRT between models A/B and models 1/2: chi-square, DF and p-value.
{phang}{cmd:r(model_#)}: Item difficulties and latent trait of model 2 and 4 : Estimates, standard error, confidence interval at 95%, chi-square, DF and p-value.
{title:Examples}
{phang}{cmd: . rosali22 itemA1 itemA2 itemA3 itemB1 itemB2 itemB3, id(mat) } {it: // 3 items : A = time1 & B = time2 }
{phang}{cmd: . rosali22 it1_t1-it9_t2 , id(idpat) moda(4 4 7 7 7 7 7 7 7) group(type_c) } {it: // 9 items, 4 answers for two first items and seven for others, detection by group of type_c }
{title:Authors}
{phang} Myriam Blanchin, Research engineer, PhD, SPHERE - UMR INSERM U1246, "methodS in Patient-centered outomes and HEalth ResEarch", University of Nantes, France {browse "mailto:myriam.blanchin@univ-nantes.fr":myriam.blanchin@univ-nantes.fr}
{phang}Priscilla Brisson, SPHERE - UMR INSERM U1246, "methodS in Patient-centered outomes and HEalth ResEarch", University of Nantes, France
{browse "mailto:priscilla.brisson@univ-nantes.fr":priscilla.brisson@univ-nantes.fr}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,162 @@
*! Version 1 20July2015
************************************************************************************************************
* rsbynpirt: Traces of items
* Version 1: July 20, 2015 /*ICC*/
*
* Historic:
* Version 1 (2015-07-20): Jean-Benoit Hardouin
*
* Jean-benoit Hardouin, phD, Assistant Professor
* Team of Biostatistics, Clinical Research and Subjective Measures in Health Sciences
* University of Nantes - Faculty of Pharmaceutical Sciences
* France
* jean-benoit.hardouin@anaqol.org
*
* News about this program :http://www.anaqol.org
*
* Copyright 2015 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 rsbynpirt
version 8.0
syntax varlist(numeric min=4) [, noGraph]
preserve
local nbitems : word count `varlist'
tokenize `varlist'
if mod(`nbitems',2)!=0 {
di in red "You must indicate an even number of items"
exit
}
else {
local nbitems=`nbitems'/2
}
local listofitems1
local listofitems2
forvalues i=1/`nbitems' {
local listofitems1 `listofitems1' ``i''
local listofitems2 `listofitems2' ``=`i'+`nbitems'''
}
tempvar varscore1 varscore2
qui gen `varscore1'=0
qui gen `varscore2'=0
label variable `varscore1' "Total score time 1"
label variable `varscore2' "Total score time 2"
local scoremax=0
local flag=0
local modamax=0
forvalues i=1/`nbitems' {
qui replace `varscore1'=`varscore1'+``i''
qui replace `varscore2'=`varscore2'+``=`i'+`nbitems'''
qui su ``i''
local modamax`i'=r(max)
qui su ``=`i'+`nbitems'''
local modamax`i'=r(max)
if r(min)!=0 {
local flag=1
}
local scoremax=`scoremax'+`modamax`i''
if `modamax`i''!=1 {
local flagbin=0
}
if `modamax`i''>`modamax' {
local modamax=`modamax`i''
}
}
if `flag'==1 {
di as error "The lower modality of the item must be 0"
exit
}
if "`flagbin'"!=""&"`logistic'"!="" {
di as error "The logistic option is not possible with polytomous items"
exit
}
qui su `varscore1'
local maxscore=r(max)
qui su `varscore1'
if `r(max)'>`maxscore' {
local maxscore=r(max)
}
tempfile rsbynpirtfile rsbynpirtfile1 rsbynpirtfile2
tempvar score
qui save `rsbynpirtfile', replace
qui traces `listofitems1', nograph icc saveicc
qui drop _all
*matrix list r(matscore)
tempname mat1
qui matrix `mat1'=r(matscore)
qui svmat `mat1', names(t1item)
forvalues i=1/`nbitems' {
local j: word `i' of `listofitems1'
qui rename t1item`i' `j'
}
qui rename t1item`=`nbitems'+1' `score'
qui contract `score' `listofitems1'
qui sort `score'
qui save `rsbynpirtfile1', replace
qui use `rsbynpirtfile', clear
qui traces `listofitems2', nograph icc saveicc
qui drop _all
tempname mat2
qui matrix `mat2'=r(matscore)
qui svmat `mat2', names(t2item)
forvalues i=1/`nbitems' {
local j: word `i' of `listofitems2'
qui rename t2item`i' `j'
}
qui rename t2item`=`nbitems'+1' `score'
qui contract `score' `listofitems2'
qui sort `score'
qui merge 1:1 `score' using `rsbynpirtfile1'
if "`graph'"=="" {
forvalues i=1/`nbitems' {
twoway (line ``i'' `score') (line ``=`i'+`nbitems''' `score'), name(``i'',replace)
}
}
qui drop if `score'==0|`score'==`scoremax'
di
di "Items" _col(18) "AUC t1" _col(28) "AUC t2" _col(38) "Var AUC" _col(46) "Diff ICC" _col(57) "SD Diff"
di "{hline 63}"
forvalues i=1/`nbitems' {
qui su ``i''
local AUC``i''=r(sum)
local AUC``i''=(`AUC``i'''+`modamax`i''/2)/(`scoremax'*`modamax`i'')*100
qui su ``=`i'+`nbitems'''
local AUC`=`i'+`nbitems''=r(sum)
local AUC`=`i'+`nbitems''=(`AUC`=`i'+`nbitems'''+`modamax`i''/2)/(`scoremax'*`modamax`i'')*100
tempname diff``i''
gen `diff``i'''=abs(``i''-``=`i'+`nbitems''')
qui su `diff``i'''
local d``i''=`r(sum)'/(`scoremax'*`modamax`i'')*100
local var``i''=`r(sd)'*100
di "``i''/``=`i'+`nbitems'''" _col(20) %4.1f `AUC``i''' _col(30) %4.1f `AUC`=`i'+`nbitems''' _col(40) %5.1f `=`AUC``i'''-`AUC`=`i'+`nbitems'''' _col(50) %4.1f `d``i''' _col(60) %4.1f `var``i'''
}
qui restore , preserve
end

View File

@ -0,0 +1,832 @@
*! version 1.4 29January2014
*! Jean-Benoit Hardouin
************************************************************************************************************
* rsoort: Response Shift detection with the Oort procedure
*
* Historic:
* Version 1 (2013-02-25): Jean-Benoit Hardouin
* Version 1.1 (2013-06-03): Jean-Benoit Hardouin /*some improvements*/
* Version 1.2 (2013-06-03): Jean-Benoit Hardouin /*model1 model2 model3 and covariances options*/
* Version 1.3 (2013-06-03): Jean-Benoit Hardouin /**/
* Version 1.4 (2014-01-29): Jean-Benoit Hardouin /*add an iterate option on model 1*/
*
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
* jean-benoit.hardouin@univ-nantes.fr
*
* Copyright 2013-2014 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define rsoort,eclass
syntax varlist(min=2 numeric) [if] [in] [,METHod(string) nom1 nocov12 UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPrioritization(varlist) noSearch html(string) model1 model2 model4 COVariances(string) MATrixrs(string)]
tempfile saversoort
qui save `saversoort',replace
preserve
if "`matrixrs'"!="" {
if "`uniformrecalibration'"!="" {
di in red "You cannot use the {bf:matrixrs} and the {bf:uniformrecalibration} options in the same time"
error
}
if "`nonuniformrecalibration'"!="" {
di in red "You cannot use the {bf:matrixrs} and the {bf:nonuniformrecalibration} options in the same time"
error
}
if "`reprioritization'"!="" {
di in red "You cannot use the {bf:matrixrs} and the {bf:reprioritization} options in the same time"
error
}
}
if "`html'" != "" {
di "<!-- SphereCalc start of response -->"
}
if "`if'"!=""|"`in'"!="" {
qui keep `if' `in'
}
tokenize `varlist'
local nbitems:word count `varlist'
local mod=mod(`nbitems',2)
if `mod'!=0 {
di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
error
}
if "`method'"=="" {
local method "ml"
}
local nbitems=`nbitems'/2
if "`html'"== "" {
di _col(20) "{hline 30}"
di _col(20) in gr "Time 1" _col(40) "Time 2"
di _col(20) "{hline 30}"
forvalues i=1/`nbitems' {
di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
}
di _col(20) "{hline 30}"
}
else {
di "<table id=" _char(34) "rsoorttimetable" _char(34) "class=" _char(34) "restable" _char(34) ">"
di "<caption></caption>"
di "<thead><tr><th>Time 1</th><th>Time2</th></tr></thead>"
di "<tbody>"
forvalues i=1/`nbitems' {
di "<tr><td>``i''</td><td>``=`i'+`nbitems'''</td></tr>"
}
di "</tbody></table>"
}
/**************************************************************************************************************
Model 1
***************************************************************************************************************/
if "`model1'"=="" {
local qui qui
}
else {
local qui
}
local cov12b
forvalues i=1/`nbitems' {
local cov12b `cov12b' e.``i''*e.``=`i'+`nbitems'''
}
if "`cov12'"!="" {
local cov12b
}
if "`m1'"=="" {
`qui' sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covariances') iterate(100)
qui estat gof, stat(all)
local tli1=r(tli)
local cfi1=r(cfi)
local srmr1=r(srmr)
local rmsea1=r(rmsea)
local ubrmsea1=r(ub90_rmsea)
local lbrmsea1=r(lb90_rmsea)
local chi21=r(chi2_ms)
local df1=r(df_ms)
local dfc1=6*`nbitems'+1
local p1=r(p_ms)
local bic1=r(bic)
}
else {
local chi21=.
local df1=.
}
*di
*di in green " ***********************************Model 1********************************************"
*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
/**************************************************************************************************************
Model 2
***************************************************************************************************************/
local sem
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local sem `sem' `sem`i''
local var `var' `var`i''
}
if "`model2'"=="" {
local qui qui
}
else {
local qui
}
di "`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')"
`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange2=`b'[1,`=`nbitems'*4+1']
local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof, stat(all)
local tli2=r(tli)
local cfi2=r(cfi)
local srmr2=r(srmr)
local rmsea2=r(rmsea)
local ubrmsea2=r(ub90_rmsea)
local lbrmsea2=r(lb90_rmsea)
local chi22=r(chi2_ms)
local df2=r(df_ms)
local dfc2=3*`nbitems'+3
local p2=r(p_ms)
local bic2=r(bic)
local chi221=abs(`chi21'-`chi22')
local df21=`df2'-`df1'
local p21=1-chi2(`df21',`chi221')
if "`html'" != "" {
di "<table id=rsoortglobaltable class=restable >"
di "<caption></caption>"
*di "<thead><tr><th></th><th></th><th colspan=3>Test of global Response-Shift</th><th colspan=3>Comparison with model 1</th></tr>"
di "<tr><th>Models</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th></tr></thead>"
di "<tbody>"
di "<tr><td>Model 1</td><td>" %8.2f `chi21' "</td><td>" %4.0f `df1' "</td><td>" %6.4f `p1' "</td><td>" %7.2f `bic1' "</td></tr>"
di "<tr><td>Model 2</td><td>" %8.2f `chi22' "</td><td>" %4.0f `df2' "</td><td>" %6.4f `p2' "</td><td>" %7.2f `bic2' "</td></tr>"
di "</tbody></table>"
}
else {
di "{hline 51}"
di in gr /*_col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"*/
di in gr "Models" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" /*_col(39) "Chi-square" _col(54) "df" _col(59) "p-value" *_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 51}"
di in gr "Model 1" _col(20) %8.2f in ye `chi21' _col(30) %4.0f `df1' _col(37) %6.4f `p1' _col(45) %7.2f `bic1'
di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(30) %4.0f `df2' _col(37) %6.4f `p2' _col(45) %7.2f `bic2' /*_col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' *_col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'*/
di "{hline 51}"
}
/**************************************************************************************************************
Model 3
***************************************************************************************************************/
/**************************************************************************************************************
Model 3 / Non uniform recalibration
***************************************************************************************************************/
tempname RS RSprec
qui matrix `RS'=J(`nbitems',3,0)
qui matrix `RSprec'=J(`nbitems',3,0)
local df3=`dfc2'
*set trace on
if "`matrixrs'"=="" {
forvalues i=1/`nbitems' {
local nbUR:word count `uniformrecalibration'
forvalues j=1/`nbUR' {
local itemj: word `j' of `uniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',2]=1
}
}
local nbNUR:word count `nonuniformrecalibration'
forvalues j=1/`nbNUR' {
local itemj: word `j' of `nonuniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',1]=1
}
}
local nbR:word count `reprioritization'
forvalues j=1/`nbR' {
local itemj: word `j' of `reprioritization'
if "``i''"=="`itemj'" {
matrix `RS'[`i',3]=1
}
}
}
}
else {
matrix `RS'=`matrixrs'
}
*matrix list `RS'
if "`search'"=="" {
if "`html'"=="" {
di
di "{hline 88}"
di in green _col(40) "Model 3"
di "{hline 88}"
di
di in white _col(10) "Non uniform Recalibration"
}
else {
di "<h2><br>Model 3</h2>"
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Non uniform Recalibration</caption>"
}
local continue=1
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
}
local prec_chi2=`chi22'
local testNU_varchi2=0
local testNU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testNU_varchi2_temp=0
local testNU_p_temp=0
local testNU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
local var
forvalues j=1/`nbitems' {
local sem
local var
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',1]==0&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `var`i''
}
if `RS'[`i',1]==1&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==0 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==1 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
local continue=1
local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
local testNU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
}
else {
if "`html'" != "" {
di "<tr><td>``j''</td><td>Unavailable</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable"
}
}
local ++cpt
}
}
if (`testNU_item_temp'!=0) {
matrix `RS'[`testNU_item_temp',1]=1
local ++df3
local testNU_varchi2=`testNU_varchi2_temp'
local testNU_p=`testNU_p_temp'
local testNU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 3 / Uniform recalibration
***************************************************************************************************************/
if "`html'"=="" {
di
di in white _col(10) "Uniform Recalibration"
}
else {
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Uniform Recalibration</caption>"
}
local continue=1
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testU_varchi2_temp=0
local testU_p_temp=0
local testU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
if `RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==0 {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==1 {
local sem `sem' `semrecU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
local continue=1
local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
local testU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
}
else {
if "`html'" != "" {
di "<tr><td>``j''</td><td>Unavailable</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable"
}
}
local ++cpt
}
}
if (`testU_item_temp'!=0) {
matrix `RS'[`testU_item_temp',2]=1
local ++df3
local testU_varchi2=`testU_varchi2_temp'
local testU_p=`testU_p_temp'
local testU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 3 / Reprioritization
***************************************************************************************************************/
if "`html'"=="" {
di
di in white _col(10) "Reprioritization"
}
else {
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Reprioritization</caption>"
}
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testR_varchi2_temp=0
local testR_p_temp=0
local testR_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `semrep`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
local sem `sem' `semrecUrep`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
local continue=1
local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
local testR_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
}
else {
if "`html'" != "" {
di "<tr><td>``j''</td><td>Unavailable</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable"
}
}
local ++cpt
}
}
if (`testR_item_temp'!=0) {
matrix `RS'[`testR_item_temp',3]=1
local ++df3
local testR_varchi2=`testR_varchi2_temp'
local testR_p=`testR_p_temp'
local testR_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
}
/**************************************************************************************************************
Model 3 Final
***************************************************************************************************************/
di
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==0 {
local sem "`sem' `sem`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==1 {
local sem "`sem' `semrep`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==0 {
local sem "`sem' `semrecU`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==1 {
local sem "`sem' `semrecUrep`i''"
}
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof
local tli3=r(tli)
local cfi3=r(cfi)
local srmr3=r(srmr)
local rmsea3=r(rmsea)
local ubrmsea3=r(ub90_rmsea)
local lbrmsea3=r(lb90_rmsea)
local chi23=r(chi2_ms)
local dfc3=`df3'
local p3=r(p_ms)
local bic3=r(bic)
/**************************************************************************************************************
Bilan
***************************************************************************************************************/
if "`html'"=="" {
di
di "{hline 74}"
di in gr _col(22) "Non uniform" _col(46) "Uniform"
di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(58) "Reprioritization"
di "{hline 74}"
}
else {
di "<table id=rsoortbilantable class=restable >"
di "<caption></caption>"
di "<thead><tr><th>Items</th><th>Non-uniform<br>Recalibration</th><th>Uniform<br>Recalibration</th><th><br>Repriorisation</th></tr></thead>"
di "<tbody>"
}
forvalues i=1/`nbitems' {
local recNU
local recU
local rep
if (`RS'[`i',1]==1) {
local recNU "*"
}
if (`RS'[`i',2]==1) {
local recU "*"
}
if (`RS'[`i',3]==1) {
local rep "*"
}
if "`html'"=="" {
di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
}
else {
di "<tr><td>``i''</td><td>`recNU'</td><td>`recU'</td><td>`rep'</td></tr>"
}
}
if "`html'"=="" {
di "{hline 74}"
}
else {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 4
***************************************************************************************************************/
if "`model4'"=="" {
local qui qui
}
else {
local qui
}
`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) cov(`cov12b' `covariances') method(`method')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof,stat(all)
local tli4=r(tli)
local cfi4=r(cfi)
local srmr4=r(srmr)
local rmsea4=r(rmsea)
local ubrmsea4=r(ub90_rmsea)
local lbrmsea4=r(lb90_rmsea)
local chi24=r(chi2_ms)
local df4=r(df_ms)
local dfc4=`df3'+1
local p4=r(p_ms)
local chi2encours=r(chi2_ms)
local bic4=r(bic)
local z=`truechange'/sqrt(`Vtruechange')
if "`html'" != "" {
di "<table id=rsoortM4table class=restable >"
di "<caption></caption>"
di "<thead><tr><th>Models</th><th>chi2</th><th>df</th><th><I>p</I></th><th>BIC</th><th>RMSEA</th><th>IC<sub>90%</sub>(RMSEA)</th><th>SRMR</th><th>CFI</th><th>TLI</th></tr></thead>"
di "<tbody>"
if "`m1'"=="" {
di "<tr><td>Model 1</td><td>" %8.2f `chi21' "</td><td>" %4.0f `df1' "</td><td>" %7.2f `bic1' "</td><td>" %6.4f `p1' "</td><td>" %6.4f `rmsea1' "</td><td>" %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' "</td><td>" %6.4f `srmr1' "</td><td>" %6.2f `cfi1' "</td><td>" %6.2f `tli1' "</td></tr>"
}
di "<tr><td>Model 2</td><td>" %8.2f `chi22' "</td><td>" %4.0f `df2' "</td><td>" %7.2f `bic2' "</td><td>" %6.4f `p2' "</td><td>" %6.4f `rmsea2' "</td><td>" %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' "</td><td>" %6.4f `srmr2' "</td><td>" %6.2f `cfi2' "</td><td>" %6.2f `tli2' "</td></tr>"
di "<tr><td>Model 4</td><td>" %8.2f `chi24' "</td><td>" %4.0f `df4' "</td><td>" %7.2f `bic4' "</td><td>" %6.4f `p4' "</td><td>" %6.4f `rmsea4' "</td><td>" %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' "</td><td>" %6.4f `srmr4' "</td><td>" %6.2f `cfi4' "</td><td>" %6.2f `tli4' "</td></tr>"
di "</tbody></table>"
}
else {
di
di "{hline 95}"
di in gr "Models" _col(14) "chi2" _col(22) "df" _col(31) "p" _col(40) "BIC" _col(47) "RMSEA" _col(55) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
di "{hline 95}"
if "`m1'"=="" {
di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `df1' _col(26) %6.4f `p1' _col(36) %7.2f `bic1' _col(46) %6.4f `rmsea1' _col(54) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
}
di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `df2' _col(26) %6.4f `p2' _col(36) %7.2f `bic2' _col(46) %6.4f `rmsea2' _col(54) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `df4' _col(26) %6.4f `p4' _col(36) %7.2f `bic4' _col(46) %6.4f `rmsea4' _col(54) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
di "{hline 95}"
}
if "`html'" != "" {
di "<table id=rsoorttruechangetable class=restable >"
di "<caption></caption>"
di "<thead><tr><th></th><th>Estimation</th><th>s.e.</th><th>z</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
di "<tr><td>True change (Model 2)</td><td>" %8.4f `truechange2' "</td><td>" %8.4f `=sqrt(`Vtruechange2')' "</td><td>" %6.2f `=`truechange2'/sqrt(`Vtruechange2')' "</td><td>" %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' "</td></tr>"
di "<tr><td>True change (Model 4)</td><td>" %8.4f `truechange' "</td><td>" %8.4f `=sqrt(`Vtruechange')' "</td><td>" %6.2f `=`truechange'/sqrt(`Vtruechange')' "</td><td>" %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' "</td></tr>"
di "</tbody></table>"
}
else {
di
di "{hline 77}"
di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
di "{hline 77}"
di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
di "{hline 77}"
di
}
qui use `saversoort',clear
end

View File

@ -0,0 +1,69 @@
{smcl}
{* 3June2013}{...}
{hline}
help for {hi:rsoort}{right:Jean-Benoit Hardouin}
{hline}
{title: Oort's Structural Equations Modeling (SEM) based procedure to detect Response Shift}
{p 8 14 2}{cmd:rsoort} {it:varlist} {ifin} [{cmd:,} {cmdab:meth:od}({it:string}) {cmdab:unif:ormrecalibration}({it:varlist}) {cmdab:nonunif:ormrecalibration}({it:varlist}) {cmdab:rep:rioritization}({it:varlist}) {cmdab:nos:earch}]
{p 8 14 2}{it:varlist} is a list of two or more existing variables. You must first enter the list of variables to first measurement followed by the list of variables (in the same order) in the second measurement time.
{title:Description}
{p 4 8 2}{cmd:rsoort} provides the Oort's procedure based on Structural Equation Modeling (SEM) in order to detect Response-Shift in a set of variables.
{title:Options}
{p 4 8 2}{cmd:method}. By default, maximum likelihood estimations of the models parameters are used. You can use alternative methods of estimation like {cmd:mlmv} for
maximum likelihood handling missing data or {cmd:adf} for asymptotic distribution free method.
{p 4 8 2}{cmd:uniformrecalibation} allows defining variables suspected to be affected by uniform recalibration (you should give the name of the variable to the first
measurement). In this case, the procedure force the concerned variable to be affected by uniform recalibration and this kind of response-shift is searched only on the
other variables.
{p 4 8 2}{cmd:nonuniformrecalibation} allows defining variables suspected to be affected by non uniform recalibration (you should give the name of the variable to the
first measurement). In this case, the procedure force the concerned variable to be affected by non uniform recalibration and this kind of response-shift is searched
only on the other variables.
{p 4 8 2}{cmd:reprioritization} allows defining variables suspected to be affected by reprioritization (you should give the name of the variable to the first
measurement). In this case, the procedure force the concerned variable to be affected by reprioritization and this kind of response-shift is searched only on the other
variables.
{p 4 8 2}{cmd:nosearch} avoids the procedure to be run (this is useful only if you precise the {cmd:uniformrecalibation}, {cmd:nonuniformrecalibation} or
{cmd:reprioritization} options)
{title:Example}
{p 8 8}{inp:. rsoort var1t1-var10t1 var1t2-var10t2}
{p 8 8}{inp:. rsoort var1t1-var10t1 var1t2-var10t2, unif(var3t1 var7t1) rep(var8t1)}
{p 8 8}{inp:. rsoort var1t1-var10t1 var1t2-var10t2, unif(var3t1 var7t1) rep(var8t1) nosearch}
{title:References}
{p 4 8 2}Oort F.J. Using structural equation modeling to detect response shifts and true change. {it: Quality of life Research}, vol.14(3), 2005, pp. 587-598.
{p 4 8 2}Oort F.J., Visser M.R., Sprangers M.A. An application of structural equation modeling to detect response shifts and true change in quality of life data from cancer patients undergoing invasive surgery. {it: Quality of life Research}, vol.14(3), 2005, pp. 599-609.
{p 4 8 2}Oort F.J. Towards a formal definition of response shift (in reply to G.W. Donaldson)., {it: Quality of life Research}, vol.14(10), 2005, pp. 2353-2355.
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
{p 4 8 2}EA 4275-SPHERE "Team of Biostatistics, Pharmacoepidemiology 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}
{title:Also see}
{p 4 13 2}Online: help for {help sem}{p_end}

Binary file not shown.

View File

@ -0,0 +1,770 @@
*! version 1.1 3June2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* rsoort: Response Shift detection with the Oort procedure
*
* Historic:
* Version 1 (2013-02-25): Jean-Benoit Hardouin
* Version 1.1 (2013-06-03): Jean-Benoit Hardouin /*some improvements*/
* Version 1.2 (2013-06-03): Jean-Benoit Hardouin /*model1 model2 model3 and covariances options*/
*
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
* jean-benoit.hardouin@univ-nantes.fr
*
* Copyright 2013 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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define rsoort,eclass
syntax varlist(min=2 numeric) [if] [in] [,METHod(string) UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPrioritization(varlist) noSearch html(string) model1 model2 model4 COVariances(string)]
tempfile saversoort
qui save `saversoort',replace
if "`html'" != "" {
di "<!-- SphereCalc start of response -->"
}
if "`if'"!=""|"`in'"!="" {
qui keep `if' `in'
}
tokenize `varlist'
local nbitems:word count `varlist'
local mod=mod(`nbitems',2)
if `mod'!=0 {
di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
error
}
if "`method'"=="" {
local method "ml"
}
local nbitems=`nbitems'/2
if "`html'"== "" {
di _col(20) "{hline 30}"
di _col(20) in gr "Time 1" _col(40) "Time 2"
di _col(20) "{hline 30}"
forvalues i=1/`nbitems' {
di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
}
di _col(20) "{hline 30}"
}
else {
di "<table id=" _char(34) "rsoorttimetable" _char(34) "class=" _char(34) "restable" _char(34) ">"
di "<caption></caption>"
di "<thead><tr><th>Time 1</th><th>Time2</th></tr></thead>"
di "<tbody>"
forvalues i=1/`nbitems' {
di "<tr><td>``i''</td><td>``=`i'+`nbitems'''</td></tr>"
}
di "</tbody></table>"
}
/**************************************************************************************************************
Model 1
***************************************************************************************************************/
if "`model1'"=="" {
local qui qui
}
else {
local qui
}
`qui' sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`covariances')
qui estat gof, stat(all)
local tli1=r(tli)
local cfi1=r(cfi)
local srmr1=r(srmr)
local rmsea1=r(rmsea)
local ubrmsea1=r(ub90_rmsea)
local lbrmsea1=r(lb90_rmsea)
local chi21=r(chi2_ms)
local df1=r(df_ms)
local dfc1=6*`nbitems'+1
local p1=r(p_ms)
local bic1=r(bic)
*di
*di in green " ***********************************Model 1********************************************"
*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
/**************************************************************************************************************
Model 2
***************************************************************************************************************/
local sem
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local sem `sem' `sem`i''
local var `var' `var`i''
}
if "`model2'"=="" {
local qui qui
}
else {
local qui
}
`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances'
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange2=`b'[1,`=`nbitems'*4+1']
local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof, stat(all)
local tli2=r(tli)
local cfi2=r(cfi)
local srmr2=r(srmr)
local rmsea2=r(rmsea)
local ubrmsea2=r(ub90_rmsea)
local lbrmsea2=r(lb90_rmsea)
local chi22=r(chi2_ms)
local df2=r(df_ms)
local dfc2=3*`nbitems'+3
local p2=r(p_ms)
local bic2=r(bic)
local chi221=abs(`chi21'-`chi22')
local df21=`df2'-`df1'
local p21=1-chi2(`df21',`chi221')
if "`html'" != "" {
di "<table id=rsoortglobaltable class=restable >"
di "<caption></caption>"
*di "<thead><tr><th></th><th></th><th colspan=3>Test of global Response-Shift</th><th colspan=3>Comparison with model 1</th></tr>"
di "<tr><th>Models</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th></tr></thead>"
di "<tbody>"
di "<tr><td>Model 1</td><td>" %8.2f `chi21' "</td><td>" %4.0f `df1' "</td><td>" %6.4f `p1' "</td><td>" %7.2f `bic1' "</td></tr>"
di "<tr><td>Model 2</td><td>" %8.2f `chi22' "</td><td>" %4.0f `df2' "</td><td>" %6.4f `p2' "</td><td>" %7.2f `bic2' "</td></tr>"
di "</tbody></table>"
}
else {
di "{hline 51}"
di in gr /*_col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"*/
di in gr "Models" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" /*_col(39) "Chi-square" _col(54) "df" _col(59) "p-value" *_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 51}"
di in gr "Model 1" _col(20) %8.2f in ye `chi21' _col(30) %4.0f `df1' _col(37) %6.4f `p1' _col(45) %7.2f `bic1'
di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(30) %4.0f `df2' _col(37) %6.4f `p2' _col(45) %7.2f `bic2' /*_col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' *_col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'*/
di "{hline 51}"
}
/**************************************************************************************************************
Model 3
***************************************************************************************************************/
/**************************************************************************************************************
Model 3 / Non uniform recalibration
***************************************************************************************************************/
tempname RS RSprec
qui matrix `RS'=J(`nbitems',3,0)
qui matrix `RSprec'=J(`nbitems',3,0)
local df3=`dfc2'
*set trace on
forvalues i=1/`nbitems' {
local nbUR:word count `uniformrecalibration'
forvalues j=1/`nbUR' {
local itemj: word `j' of `uniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',2]=1
}
}
local nbNUR:word count `nonuniformrecalibration'
forvalues j=1/`nbNUR' {
local itemj: word `j' of `nonuniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',1]=1
}
}
local nbR:word count `reprioritization'
forvalues j=1/`nbR' {
local itemj: word `j' of `reprioritization'
if "``i''"=="`itemj'" {
matrix `RS'[`i',3]=1
}
}
}
*matrix list `RS'
if "`search'"=="" {
if "`html'"=="" {
di
di "{hline 88}"
di in green _col(40) "Model 3"
di "{hline 88}"
di
di in white _col(10) "Non uniform Recalibration"
}
else {
di "<h2><br>Model 3</h2>"
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Non uniform Recalibration</caption>"
}
local continue=1
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
}
local prec_chi2=`chi22'
local testNU_varchi2=0
local testNU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testNU_varchi2_temp=0
local testNU_p_temp=0
local testNU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
local var
forvalues j=1/`nbitems' {
local sem
local var
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',1]==0&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `var`i''
}
if `RS'[`i',1]==1&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==0 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==1 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances'
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
local continue=1
local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
local testNU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
local ++cpt
}
}
if (`testNU_item_temp'!=0) {
matrix `RS'[`testNU_item_temp',1]=1
local ++df3
local testNU_varchi2=`testNU_varchi2_temp'
local testNU_p=`testNU_p_temp'
local testNU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 3 / Uniform recalibration
***************************************************************************************************************/
if "`html'"=="" {
di
di in white _col(10) "Uniform Recalibration"
}
else {
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Uniform Recalibration</caption>"
}
local continue=1
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testU_varchi2_temp=0
local testU_p_temp=0
local testU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
if `RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==0 {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==1 {
local sem `sem' `semrecU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances'
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
local continue=1
local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
local testU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
local ++cpt
}
}
if (`testU_item_temp'!=0) {
matrix `RS'[`testU_item_temp',2]=1
local ++df3
local testU_varchi2=`testU_varchi2_temp'
local testU_p=`testU_p_temp'
local testU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 3 / Reprioritization
***************************************************************************************************************/
if "`html'"=="" {
di
di in white _col(10) "Reprioritization"
}
else {
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Reprioritization</caption>"
}
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testR_varchi2_temp=0
local testR_p_temp=0
local testR_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `semrep`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
local sem `sem' `semrecUrep`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances'
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
local continue=1
local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
local testR_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
}
else {
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>Unavailable</td></tr>"
}
else {
di in gr "``j''" _col(20) %8.2f in ye `chi2encours' _col(40) "Unavailable"
}
}
local ++cpt
}
}
if (`testR_item_temp'!=0) {
matrix `RS'[`testR_item_temp',3]=1
local ++df3
local testR_varchi2=`testR_varchi2_temp'
local testR_p=`testR_p_temp'
local testR_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
}
/**************************************************************************************************************
Model 3 Final
***************************************************************************************************************/
di
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==0 {
local sem "`sem' `sem`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==1 {
local sem "`sem' `semrep`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==0 {
local sem "`sem' `semrecU`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==1 {
local sem "`sem' `semrecUrep`i''"
}
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') `covariances'
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof
local tli3=r(tli)
local cfi3=r(cfi)
local srmr3=r(srmr)
local rmsea3=r(rmsea)
local ubrmsea3=r(ub90_rmsea)
local lbrmsea3=r(lb90_rmsea)
local chi23=r(chi2_ms)
local dfc3=`df3'
local p3=r(p_ms)
local bic3=r(bic)
/**************************************************************************************************************
Bilan
***************************************************************************************************************/
if "`html'"=="" {
di
di "{hline 74}"
di in gr _col(22) "Non uniform" _col(46) "Uniform"
di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(58) "Reprioritization"
di "{hline 74}"
}
else {
di "<table id=rsoortbilantable class=restable >"
di "<caption></caption>"
di "<thead><tr><th>Items</th><th>Non-uniform<br>Recalibration</th><th>Uniform<br>Recalibration</th><th><br>Repriorisation</th></tr></thead>"
di "<tbody>"
}
forvalues i=1/`nbitems' {
local recNU
local recU
local rep
if (`RS'[`i',1]==1) {
local recNU "*"
}
if (`RS'[`i',2]==1) {
local recU "*"
}
if (`RS'[`i',3]==1) {
local rep "*"
}
if "`html'"=="" {
di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
}
else {
di "<tr><td>``i''</td><td>`recNU'</td><td>`recU'</td><td>`rep'</td></tr>"
}
}
if "`html'"=="" {
di "{hline 74}"
}
else {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 4
***************************************************************************************************************/
if "`model4'"=="" {
local qui qui
}
else {
local qui
}
`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) `covariances'
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof,stat(all)
local tli4=r(tli)
local cfi4=r(cfi)
local srmr4=r(srmr)
local rmsea4=r(rmsea)
local ubrmsea4=r(ub90_rmsea)
local lbrmsea4=r(lb90_rmsea)
local chi24=r(chi2_ms)
local dfc4=`df3'+1
local p4=r(p_ms)
local chi2encours=r(chi2_ms)
local bic4=r(bic)
local z=`truechange'/sqrt(`Vtruechange')
if "`html'" != "" {
di "<table id=rsoortM4table class=restable >"
di "<caption></caption>"
di "<thead><tr><th>Models</th><th>chi2</th><th>df</th><th><I>p</I></th><th>BIC</th><th>RMSEA</th><th>IC<sub>90%</sub>(RMSEA)</th><th>SRMR</th><th>CFI</th><th>TLI</th></tr></thead>"
di "<tbody>"
di "<tr><td>Model 1</td><td>" %8.2f `chi21' "</td><td>" %4.0f `dfc1' "</td><td>" %7.2f `bic1' "</td><td>" %6.4f `p1' "</td><td>" %6.4f `rmsea1' "</td><td>" %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' "</td><td>" %6.4f `srmr1' "</td><td>" %6.2f `cfi1' "</td><td>" %6.2f `tli1' "</td></tr>"
di "<tr><td>Model 2</td><td>" %8.2f `chi22' "</td><td>" %4.0f `dfc2' "</td><td>" %7.2f `bic2' "</td><td>" %6.4f `p2' "</td><td>" %6.4f `rmsea2' "</td><td>" %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' "</td><td>" %6.4f `srmr2' "</td><td>" %6.2f `cfi2' "</td><td>" %6.2f `tli2' "</td></tr>"
di "<tr><td>Model 4</td><td>" %8.2f `chi24' "</td><td>" %4.0f `dfc4' "</td><td>" %7.2f `bic4' "</td><td>" %6.4f `p4' "</td><td>" %6.4f `rmsea4' "</td><td>" %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' "</td><td>" %6.4f `srmr4' "</td><td>" %6.2f `cfi4' "</td><td>" %6.2f `tli4' "</td></tr>"
di "</tbody></table>"
}
else {
di
di "{hline 95}"
di in gr "Models" _col(14) "chi2" _col(22) "df" _col(31) "p" _col(40) "BIC" _col(47) "RMSEA" _col(55) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
di "{hline 95}"
di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(26) %6.4f `p1' _col(36) %7.2f `bic1' _col(46) %6.4f `rmsea1' _col(54) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `dfc2' _col(26) %6.4f `p2' _col(36) %7.2f `bic2' _col(46) %6.4f `rmsea2' _col(54) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `dfc4' _col(26) %6.4f `p4' _col(36) %7.2f `bic4' _col(46) %6.4f `rmsea4' _col(54) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
di "{hline 95}"
}
if "`html'" != "" {
di "<table id=rsoorttruechangetable class=restable >"
di "<caption></caption>"
di "<thead><tr><th></th><th>Estimation</th><th>s.e.</th><th>z</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
di "<tr><td>True change (Model 2)</td><td>" %8.4f `truechange2' "</td><td>" %8.4f `=sqrt(`Vtruechange2')' "</td><td>" %6.2f `=`truechange2'/sqrt(`Vtruechange2')' "</td><td>" %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' "</td></tr>"
di "<tr><td>True change (Model 4)</td><td>" %8.4f `truechange' "</td><td>" %8.4f `=sqrt(`Vtruechange')' "</td><td>" %6.2f `=`truechange'/sqrt(`Vtruechange')' "</td><td>" %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' "</td></tr>"
di "</tbody></table>"
}
else {
di
di "{hline 77}"
di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
di "{hline 77}"
di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
di "{hline 77}"
di
}
qui use `saversoort',clear
end

View File

@ -0,0 +1,820 @@
*! version 1.3 12June2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* rsoort: Response Shift detection with the Oort procedure
*
* Historic:
* Version 1 (2013-02-25): Jean-Benoit Hardouin
* Version 1.1 (2013-06-03): Jean-Benoit Hardouin /*some improvements*/
* Version 1.2 (2013-06-03): Jean-Benoit Hardouin /*model1 model2 model3 and covariances options*/
* Version 1.3 (2013-06-03): Jean-Benoit Hardouin /**/
*
*
* Jean-benoit Hardouin - Department of Biomathematics and Biostatistics - University of Nantes - France
* EA 4275-SPHERE "bioStatistics, Pharmacoepidemiology and Human sciEnces Research tEam"
* jean-benoit.hardouin@univ-nantes.fr
*
* Copyright 2013 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
************************************************************************************************************/
/***********************************************************************************************************
INTRODUCTION
***********************************************************************************************************/
program define rsoort,eclass
syntax varlist(min=2 numeric) [if] [in] [,METHod(string) nocov12 UNIFormrecalibration(varlist) NONUNIFormrecalibration(varlist) REPrioritization(varlist) noSearch html(string) model1 model2 model4 COVariances(string) MATrixrs(string)]
tempfile saversoort
qui save `saversoort',replace
preserve
if "`matrixrs'"!="" {
if "`uniformrecalibration'"!="" {
di in red "You cannot use the {bf:matrixrs} and the {bf:uniformrecalibration} options in the same time"
error
}
if "`nonuniformrecalibration'"!="" {
di in red "You cannot use the {bf:matrixrs} and the {bf:nonuniformrecalibration} options in the same time"
error
}
if "`reprioritization'"!="" {
di in red "You cannot use the {bf:matrixrs} and the {bf:reprioritization} options in the same time"
error
}
}
if "`html'" != "" {
di "<!-- SphereCalc start of response -->"
}
if "`if'"!=""|"`in'"!="" {
qui keep `if' `in'
}
tokenize `varlist'
local nbitems:word count `varlist'
local mod=mod(`nbitems',2)
if `mod'!=0 {
di in red "You must enter an even number of items : the first half of the items represents the items in time 1 and the second half the items in time 2"
error
}
if "`method'"=="" {
local method "ml"
}
local nbitems=`nbitems'/2
if "`html'"== "" {
di _col(20) "{hline 30}"
di _col(20) in gr "Time 1" _col(40) "Time 2"
di _col(20) "{hline 30}"
forvalues i=1/`nbitems' {
di in ye _col(20) "``i''" _col(40) "``=`i'+`nbitems'''"
}
di _col(20) "{hline 30}"
}
else {
di "<table id=" _char(34) "rsoorttimetable" _char(34) "class=" _char(34) "restable" _char(34) ">"
di "<caption></caption>"
di "<thead><tr><th>Time 1</th><th>Time2</th></tr></thead>"
di "<tbody>"
forvalues i=1/`nbitems' {
di "<tr><td>``i''</td><td>``=`i'+`nbitems'''</td></tr>"
}
di "</tbody></table>"
}
/**************************************************************************************************************
Model 1
***************************************************************************************************************/
if "`model1'"=="" {
local qui qui
}
else {
local qui
}
local cov12b
forvalues i=1/`nbitems' {
local cov12b `cov12b' e.``i''*e.``=`i'+`nbitems'''
}
if "`cov12'"!="" {
local cov12b
}
`qui' sem (T1->`1'-``nbitems'')(T2->``=`nbitems'+1''-``=`nbitems'*2''),var(T1@1) var(T2@1) means(T1@0) means(T2@0) method(`method') cov(`cov12b' `covariances')
qui estat gof, stat(all)
local tli1=r(tli)
local cfi1=r(cfi)
local srmr1=r(srmr)
local rmsea1=r(rmsea)
local ubrmsea1=r(ub90_rmsea)
local lbrmsea1=r(lb90_rmsea)
local chi21=r(chi2_ms)
local df1=r(df_ms)
local dfc1=6*`nbitems'+1
local p1=r(p_ms)
local bic1=r(bic)
*di
*di in green " ***********************************Model 1********************************************"
*di in gr _col(14) "chi2" _col(22) "df" _col(35) "p" _col(41) "rmsea" _col(51) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
*di in ye _col(10) %8.2f `chi21' _col(20) %4.0f `dfc1' _col(30) %6.4f `p1' _col(40) %6.4f `rmsea1' _col(50) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
/**************************************************************************************************************
Model 2
***************************************************************************************************************/
local sem
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local sem `sem' `sem`i''
local var `var' `var`i''
}
if "`model2'"=="" {
local qui qui
}
else {
local qui
}
`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange2=`b'[1,`=`nbitems'*4+1']
local Vtruechange2=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof, stat(all)
local tli2=r(tli)
local cfi2=r(cfi)
local srmr2=r(srmr)
local rmsea2=r(rmsea)
local ubrmsea2=r(ub90_rmsea)
local lbrmsea2=r(lb90_rmsea)
local chi22=r(chi2_ms)
local df2=r(df_ms)
local dfc2=3*`nbitems'+3
local p2=r(p_ms)
local bic2=r(bic)
local chi221=abs(`chi21'-`chi22')
local df21=`df2'-`df1'
local p21=1-chi2(`df21',`chi221')
if "`html'" != "" {
di "<table id=rsoortglobaltable class=restable >"
di "<caption></caption>"
*di "<thead><tr><th></th><th></th><th colspan=3>Test of global Response-Shift</th><th colspan=3>Comparison with model 1</th></tr>"
di "<tr><th>Models</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th></tr></thead>"
di "<tbody>"
di "<tr><td>Model 1</td><td>" %8.2f `chi21' "</td><td>" %4.0f `df1' "</td><td>" %6.4f `p1' "</td><td>" %7.2f `bic1' "</td></tr>"
di "<tr><td>Model 2</td><td>" %8.2f `chi22' "</td><td>" %4.0f `df2' "</td><td>" %6.4f `p2' "</td><td>" %7.2f `bic2' "</td></tr>"
di "</tbody></table>"
}
else {
di "{hline 51}"
di in gr /*_col(39) "Test of global Response-Shift " _col(79) "Comparison with model 1"*/
di in gr "Models" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" /*_col(39) "Chi-square" _col(54) "df" _col(59) "p-value" *_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 51}"
di in gr "Model 1" _col(20) %8.2f in ye `chi21' _col(30) %4.0f `df1' _col(37) %6.4f `p1' _col(45) %7.2f `bic1'
di in gr "Model 2" _col(20) %8.2f in ye `chi22' _col(30) %4.0f `df2' _col(37) %6.4f `p2' _col(45) %7.2f `bic2' /*_col(40) %8.2f `=abs(`chi22'-`chi21')' _col(50) %6.0f `df21' %6.4f _col(60) `=1-chi2(`df21',abs(`chi22'-`chi21'))' *_col(82) %8.2f `=`=abs(`chi22'-`chi21')'' _col(90) %6.0f `df21' _col(100) %6.4f `=1-chi2(`df21',abs(`chi22'-`chi21'))'*/
di "{hline 51}"
}
/**************************************************************************************************************
Model 3
***************************************************************************************************************/
/**************************************************************************************************************
Model 3 / Non uniform recalibration
***************************************************************************************************************/
tempname RS RSprec
qui matrix `RS'=J(`nbitems',3,0)
qui matrix `RSprec'=J(`nbitems',3,0)
local df3=`dfc2'
*set trace on
if "`matrixrs'"=="" {
forvalues i=1/`nbitems' {
local nbUR:word count `uniformrecalibration'
forvalues j=1/`nbUR' {
local itemj: word `j' of `uniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',2]=1
}
}
local nbNUR:word count `nonuniformrecalibration'
forvalues j=1/`nbNUR' {
local itemj: word `j' of `nonuniformrecalibration'
if "``i''"=="`itemj'" {
matrix `RS'[`i',1]=1
}
}
local nbR:word count `reprioritization'
forvalues j=1/`nbR' {
local itemj: word `j' of `reprioritization'
if "``i''"=="`itemj'" {
matrix `RS'[`i',3]=1
}
}
}
}
else {
matrix `RS'=`matrixrs'
}
*matrix list `RS'
if "`search'"=="" {
if "`html'"=="" {
di
di "{hline 88}"
di in green _col(40) "Model 3"
di "{hline 88}"
di
di in white _col(10) "Non uniform Recalibration"
}
else {
di "<h2><br>Model 3</h2>"
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Non uniform Recalibration</caption>"
}
local continue=1
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
}
local prec_chi2=`chi22'
local testNU_varchi2=0
local testNU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testNU_varchi2_temp=0
local testNU_p_temp=0
local testNU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
local var
forvalues j=1/`nbitems' {
local sem
local var
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',1]==0&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `var`i''
}
if `RS'[`i',1]==1&`i'!=`j' {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==0 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
}
else if `i'==`j'&`RS'[`j',1]==1 {
local sem `sem' `sem`i''
local var `var' `varrecNU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testNU_varchi2_temp') {
local continue=1
local testNU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testNU_p_temp =1-chi2(1,`testNU_varchi2_temp')
local testNU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
}
else {
if "`html'" != "" {
di "<tr><td>``j''</td><td>Unavailable</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable"
}
}
local ++cpt
}
}
if (`testNU_item_temp'!=0) {
matrix `RS'[`testNU_item_temp',1]=1
local ++df3
local testNU_varchi2=`testNU_varchi2_temp'
local testNU_p=`testNU_p_temp'
local testNU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 3 / Uniform recalibration
***************************************************************************************************************/
if "`html'"=="" {
di
di in white _col(10) "Uniform Recalibration"
}
else {
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Uniform Recalibration</caption>"
}
local continue=1
local var
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testU_varchi2_temp=0
local testU_p_temp=0
local testU_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
if `RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==0 {
local sem `sem' `semrecU`i''
}
else if `i'==`j'&`RS'[`j',2]==1 {
local sem `sem' `semrecU`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testU_varchi2_temp') {
local continue=1
local testU_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testU_p_temp =1-chi2(1,`testU_varchi2_temp')
local testU_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
}
else {
if "`html'" != "" {
di "<tr><td>``j''</td><td>Unavailable</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable"
}
}
local ++cpt
}
}
if (`testU_item_temp'!=0) {
matrix `RS'[`testU_item_temp',2]=1
local ++df3
local testU_varchi2=`testU_varchi2_temp'
local testU_p=`testU_p_temp'
local testU_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 3 / Reprioritization
***************************************************************************************************************/
if "`html'"=="" {
di
di in white _col(10) "Reprioritization"
}
else {
di "<table id=rsoortM3nonuniftable class=restable >"
di "<caption>Reprioritization</caption>"
}
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
}
local testU_varchi2=0
local testU_p=1
if "`html'"=="" {
di "{hline 88}"
di in gr _col(59) "Comparison with previous model"/* _col(79) "Comparison with model 1"*/
di in gr "Items" _col(18) "Chi-square" _col(32) "df" _col(36) "p-value" _col(48) "BIC" _col(59) "Chi-square" _col(73) "df" _col(82) "p-value" /*_col(79) "Chi-square" _col(94) "df" _col(99) "p-value"*/
di "{hline 88}"
}
else {
di "<thead><tr><th></th><th></th><th></th><th></th><th></th><th colspan=3 align=left>Comparison with previous model</th></tr>"
di "<tr><th>Items</th><th>Chi-square</th><th>df</th><th>p-value</th><th>BIC</th><th>Chi-square</th><th>df</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
}
while (`continue') {
local cpt=0
local testR_varchi2_temp=0
local testR_p_temp=0
local testR_item_temp=0
local chi2encours_temp=-1
local continue=0
local sem
forvalues j=1/`nbitems' {
local sem
local already=0
forvalues i=1/`nbitems' {
if `RS'[`i',3]==0&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `sem`i''
}
else if `RS'[`i',3]==0&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecU`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==0&`i'!=`j' {
local sem `sem' `semrep`i''
}
else if `RS'[`i',3]==1&`RS'[`i',2]==1&`i'!=`j' {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==0 {
local sem `sem' `semrecUrep`i''
}
else if `i'==`j'&`RS'[`j',3]==0&`RS'[`i',2]==1&`RS'[`i',1]==1 {
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==0 {
local sem `sem' `semrep`i''
local already=1
}
else if `i'==`j'&`RS'[`j',3]==1&`RS'[`i',2]==1 {
local sem `sem' `semrecUrep`i''
local already=1
}
}
if (`already'!=1) {
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
qui estat gof
local chi2encours=r(chi2_ms)
local dfencours=r(df_ms)
local pencours=r(p_ms)
local bicencours=r(bic)
if (abs(`chi2encours'-`prec_chi2')>invchi2(1,0.95)&abs(`chi2encours'-`prec_chi2')>`testR_varchi2_temp'&`chi2encours'<`prec_chi2') {
local continue=1
local testR_varchi2_temp =abs(`chi2encours'-`prec_chi2' )
local testR_p_temp =1-chi2(1,`testR_varchi2_temp')
local testR_item_temp=`j'
local chi2encours_tmp=`chi2encours'
local tmp=`chi2encours'
}
if ( `chi2encours'<`prec_chi2') {
if "`html'" != "" {
di "<tr><td>``j''</td><td>" %8.2f `chi2encours' "</td><td>" %4.0f `dfencours' "</td><td>" %6.4f `pencours' "</td><td>" %7.2f `bicencours' "</td><td>" %8.2f `=abs(`chi2encours'-`prec_chi2' )' "</td><td>1</td><td>" %6.4f `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' "</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(20) %8.2f in ye `chi2encours' _col(30) %4.0f `dfencours' _col(37) %6.4f `pencours' _col(45) %7.2f `bicencours' _col(61) %8.2f `=abs(`chi2encours'-`prec_chi2' )' _col(74) "1" %6.4f _col(83) `=1-chi2(1,abs(`chi2encours'-`prec_chi2' ))' /*_col(82) %8.2f `=abs(`chi2encours'-`chi21')' _col(90) %6.0f `=abs(`df3'+1-`dfc1')' _col(100) %6.4f `=1-chi2(abs(`df3'+1-`dfc1'),abs(`chi2encours'-`chi21'))'*/
}
}
else {
if "`html'" != "" {
di "<tr><td>``j''</td><td>Unavailable</td></tr>"
}
else {
di in gr abbrev("``j''",14) _col(17) in ye /*%8.2f in ye `chi2encours' _col(40)*/ "Unavailable"
}
}
local ++cpt
}
}
if (`testR_item_temp'!=0) {
matrix `RS'[`testR_item_temp',3]=1
local ++df3
local testR_varchi2=`testR_varchi2_temp'
local testR_p=`testR_p_temp'
local testR_item_temp=0
local prec_chi2=`tmp'
}
if (`cpt'!=0) {
if "`html'" != "" {
di "<tr><td colspan=8><hr></td></tr>"
}
else {
di "{hline 88}"
}
}
}
if "`html'" != "" {
di "</tbody></table>"
}
}
/**************************************************************************************************************
Model 3 Final
***************************************************************************************************************/
di
local continue=1
local var
local sem
forvalues i=1/`nbitems' {
local sem`i' "(T1@load`i' _cons@int`i'->``i'') (T2@load`i' _cons@int`i'->``=`i'+`nbitems''')"
local semrecU`i' "(T1@load`i' _cons->``i'') (T2@load`i' _cons->``=`i'+`nbitems''')"
local semrecUrep`i' "(T1 _cons->``i'') (T2 _cons->``=`i'+`nbitems''')"
local semrep`i' "(T1 _cons@int`i'->``i'') (T2 _cons@int`i'->``=`i'+`nbitems''')"
local var`i' "var(e.``i''@var`i') var(e.``=`i'+`nbitems'''@var`i')"
local varrecNU`i' "var(e.``i'') var(e.``=`i'+`nbitems''')"
if `RS'[`i',1]==1 {
local var "`var' `varrecNU`i''"
}
if `RS'[`i',1]==0 {
local var "`var' `var`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==0 {
local sem "`sem' `sem`i''"
}
if `RS'[`i',2]==0&`RS'[`i',3]==1 {
local sem "`sem' `semrep`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==0 {
local sem "`sem' `semrecU`i''"
}
if `RS'[`i',2]==1&`RS'[`i',3]==1 {
local sem "`sem' `semrecUrep`i''"
}
}
qui sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) method(`method') cov(`cov12b' `covariances')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof
local tli3=r(tli)
local cfi3=r(cfi)
local srmr3=r(srmr)
local rmsea3=r(rmsea)
local ubrmsea3=r(ub90_rmsea)
local lbrmsea3=r(lb90_rmsea)
local chi23=r(chi2_ms)
local dfc3=`df3'
local p3=r(p_ms)
local bic3=r(bic)
/**************************************************************************************************************
Bilan
***************************************************************************************************************/
if "`html'"=="" {
di
di "{hline 74}"
di in gr _col(22) "Non uniform" _col(46) "Uniform"
di in gr "Items" _col(20) "Recalibration" _col(40) "Recalibration" _col(58) "Reprioritization"
di "{hline 74}"
}
else {
di "<table id=rsoortbilantable class=restable >"
di "<caption></caption>"
di "<thead><tr><th>Items</th><th>Non-uniform<br>Recalibration</th><th>Uniform<br>Recalibration</th><th><br>Repriorisation</th></tr></thead>"
di "<tbody>"
}
forvalues i=1/`nbitems' {
local recNU
local recU
local rep
if (`RS'[`i',1]==1) {
local recNU "*"
}
if (`RS'[`i',2]==1) {
local recU "*"
}
if (`RS'[`i',3]==1) {
local rep "*"
}
if "`html'"=="" {
di in gr "``i''" in ye _col(32) "`recNU'" _col(52) "`recU'" _col(73) "`rep'"
}
else {
di "<tr><td>``i''</td><td>`recNU'</td><td>`recU'</td><td>`rep'</td></tr>"
}
}
if "`html'"=="" {
di "{hline 74}"
}
else {
di "</tbody></table>"
}
/**************************************************************************************************************
Model 4
***************************************************************************************************************/
if "`model4'"=="" {
local qui qui
}
else {
local qui
}
`qui' sem `sem',var(T1@1) var(T2) means(T1@0) means(T2) `var' iterate(100) cov(`cov12b' `covariances') method(`method')
tempname b V
matrix `b'=e(b)
matrix `V'=e(V)
local truechange=`b'[1,`=`nbitems'*4+1']
local Vtruechange=`V'[`=`nbitems'*4+1',`=`nbitems'*4+1']
qui estat gof,stat(all)
local tli4=r(tli)
local cfi4=r(cfi)
local srmr4=r(srmr)
local rmsea4=r(rmsea)
local ubrmsea4=r(ub90_rmsea)
local lbrmsea4=r(lb90_rmsea)
local chi24=r(chi2_ms)
local df4=r(df_ms)
local dfc4=`df3'+1
local p4=r(p_ms)
local chi2encours=r(chi2_ms)
local bic4=r(bic)
local z=`truechange'/sqrt(`Vtruechange')
if "`html'" != "" {
di "<table id=rsoortM4table class=restable >"
di "<caption></caption>"
di "<thead><tr><th>Models</th><th>chi2</th><th>df</th><th><I>p</I></th><th>BIC</th><th>RMSEA</th><th>IC<sub>90%</sub>(RMSEA)</th><th>SRMR</th><th>CFI</th><th>TLI</th></tr></thead>"
di "<tbody>"
di "<tr><td>Model 1</td><td>" %8.2f `chi21' "</td><td>" %4.0f `df1' "</td><td>" %7.2f `bic1' "</td><td>" %6.4f `p1' "</td><td>" %6.4f `rmsea1' "</td><td>" %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' "</td><td>" %6.4f `srmr1' "</td><td>" %6.2f `cfi1' "</td><td>" %6.2f `tli1' "</td></tr>"
di "<tr><td>Model 2</td><td>" %8.2f `chi22' "</td><td>" %4.0f `df2' "</td><td>" %7.2f `bic2' "</td><td>" %6.4f `p2' "</td><td>" %6.4f `rmsea2' "</td><td>" %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' "</td><td>" %6.4f `srmr2' "</td><td>" %6.2f `cfi2' "</td><td>" %6.2f `tli2' "</td></tr>"
di "<tr><td>Model 4</td><td>" %8.2f `chi24' "</td><td>" %4.0f `df4' "</td><td>" %7.2f `bic4' "</td><td>" %6.4f `p4' "</td><td>" %6.4f `rmsea4' "</td><td>" %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' "</td><td>" %6.4f `srmr4' "</td><td>" %6.2f `cfi4' "</td><td>" %6.2f `tli4' "</td></tr>"
di "</tbody></table>"
}
else {
di
di "{hline 95}"
di in gr "Models" _col(14) "chi2" _col(22) "df" _col(31) "p" _col(40) "BIC" _col(47) "RMSEA" _col(55) "IC90%(RMSEA)" _col(72) "SRMR" _col(83) "CFI" _col(93) "TLI"
di "{hline 95}"
di in green "Model 1" in ye _col(10) %8.2f `chi21' _col(20) %4.0f `df1' _col(26) %6.4f `p1' _col(36) %7.2f `bic1' _col(46) %6.4f `rmsea1' _col(54) %6.4f `lbrmsea1' "-" %6.4f `ubrmsea1' _col(70) %6.4f `srmr1' _col(80) %6.2f `cfi1' _col(90) %6.2f `tli1'
di in green "Model 2" in ye _col(10) %8.2f `chi22' _col(20) %4.0f `df2' _col(26) %6.4f `p2' _col(36) %7.2f `bic2' _col(46) %6.4f `rmsea2' _col(54) %6.4f `lbrmsea2' "-" %6.4f `ubrmsea2' _col(70) %6.4f `srmr2' _col(80) %6.2f `cfi2' _col(90) %6.2f `tli2'
*di in green "Model 3" in ye _col(10) %8.2f `chi23' _col(20) %4.0f `dfc3' _col(30) %6.4f `p3' _col(40) %6.4f `rmsea3' _col(50) %6.4f `lbrmsea3' "-" %6.4f `ubrmsea3' _col(70) %6.4f `srmr3' _col(80) %6.2f `cfi3' _col(90) %6.2f `tli3'
di in green "Model 4" in ye _col(10) %8.2f `chi24' _col(20) %4.0f `df4' _col(26) %6.4f `p4' _col(36) %7.2f `bic4' _col(46) %6.4f `rmsea4' _col(54) %6.4f `lbrmsea4' "-" %6.4f `ubrmsea4' _col(70) %6.4f `srmr4' _col(80) %6.2f `cfi4' _col(90) %6.2f `tli4'
di "{hline 95}"
}
if "`html'" != "" {
di "<table id=rsoorttruechangetable class=restable >"
di "<caption></caption>"
di "<thead><tr><th></th><th>Estimation</th><th>s.e.</th><th>z</th><th><I>p</I>-value</th></tr></thead>"
di "<tbody>"
di "<tr><td>True change (Model 2)</td><td>" %8.4f `truechange2' "</td><td>" %8.4f `=sqrt(`Vtruechange2')' "</td><td>" %6.2f `=`truechange2'/sqrt(`Vtruechange2')' "</td><td>" %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))' "</td></tr>"
di "<tr><td>True change (Model 4)</td><td>" %8.4f `truechange' "</td><td>" %8.4f `=sqrt(`Vtruechange')' "</td><td>" %6.2f `=`truechange'/sqrt(`Vtruechange')' "</td><td>" %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))' "</td></tr>"
di "</tbody></table>"
}
else {
di
di "{hline 77}"
di _col(23) in gr "Estimation" _col(44) "s.e." _col(60) "z" _col(71) "p-value"
di "{hline 77}"
di in gr "True change (Model 2)" in ye _col(25) %8.4f `truechange2' _col(40) %8.4f `=sqrt(`Vtruechange2')' _col(56) %6.2f `=`truechange2'/sqrt(`Vtruechange2')' _col(72) %6.4f `=2-2*normal(abs(`truechange2')/sqrt(`Vtruechange2'))'
di in gr "True change (Model 4)" in ye _col(25) %8.4f `truechange' _col(40) %8.4f `=sqrt(`Vtruechange')' _col(56) %6.2f `=`truechange'/sqrt(`Vtruechange')' _col(72) %6.4f `=2-2*normal(abs(`truechange')/sqrt(`Vtruechange'))'
di "{hline 77}"
di
}
qui use `saversoort',clear
end

File diff suppressed because it is too large Load Diff