You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
375 lines
13 KiB
Plaintext
375 lines
13 KiB
Plaintext
*! 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
|