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,556 @@
*! version 1.1 8december2005
*! Jean-Benoit Hardouin
************************************************************************************************************
* Simirt: Simulation of dichotomous data following an IRT model (Rasch model,
* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM
*
* Version 1 : May 9, 2005 (Jean-Benoit Hardouin)
* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/
*
* Jean-benoit Hardouin, Regional Health Observatory of Orl<72>ans - France
* jean-benoit.hardouin@orscentre.org
*
* News about this program : http://anaqol.free.fr
* FreeIRT Project : http://freeirt.free.fr
*
* Copyright 2005 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 simirt , rclass
version 8.0
syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW GRoup(real 0) DELtagroup(real 0)]
/********************************************************************************
TESTS
********************************************************************************/
if `group'<0|`group'>1 {
di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}"
error 198
exit
}
if "`clear'"==""&"`store'"=="" {
di in red "You must use at least one of these two options: clear and/or store."
error 198
exit
}
if "`dim'"!="" {
local nbdim:word count `dim'
if `nbdim'>2 {
di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it."
error 198
exit
}
if `nbdim'==1 {
local dim1=`dim'
local nbitems=`dim1'
local dim=1
}
else if `nbdim'==2 {
local dim1:word 1 of `dim'
local dim2:word 2 of `dim'
local nbitems=`dim1'+`dim2'
local dim=2
}
else {
di in red "Your {hi:dim} option is uncorrect, please correct it. This option must indicate one or two integer(s)."
error 198
exit
}
if "`diff'"!="" {
local nbdiff:word count `diff'
if (`nbdiff'==3&`dim'==1)|(`nbdiff'==5&`dim'==2)|`nbdiff'==1 {
local typediff:word 1 of `diff'
if "`typediff'"!="gauss"&"`typediff'"!="uniform" {
local typediff values
}
}
if "`typediff'"=="values"&`nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
if "`diff'"=="" {
if `dim'==1 {
local diff gauss 0 1
}
else if `dim'==2 {
local diff gauss 0 1 0 1
}
local typediff gauss
local nbdiff:word count `diff'
}
}
else if "`dim'"==""{
if "`diff'"=="" {
di in red "You must indicate the number of items to simulate with the {hi:dim} or the {hi:diff} option(s)."
error 198
exit
}
else {
local nbdiff:word count `diff'
if `nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
}
if "`draw'"!=""&`dim'!=1 {
di in red "The {hi:draw} option is available only with unidimensional simulated data."
error 198
exit
}
if (`group'!=0|`deltagroup'!=0)&`dim'!=1 {
di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data."
error 198
exit
}
if "`prefix'"=="" {
local prefix item
}
local nbprefix:word count `prefix'
local prefix1:word 1 of `prefix'
if `dim'==2&`nbprefix'>=2 {
local prefix2:word 2 of `prefix'
}
else if `dim'==2 {
local prefix2:word 1 of `prefix'
}
if `dim'==2&"`prefix1'"=="`prefix2'" {
local prefix1 `prefix1'A
local prefix2 `prefix2'B
}
*di in ye "dim : `dim' ; diff : `diff' ; nbdiff : `nbdiff'"
local nbcov:word count `cov'
if `dim'==1&`nbcov'>1 {
di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option."
error 198
exit
}
else if `dim'==2&`nbcov'!=3&`nbcov'>0 {
di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)."
error 198
exit
}
else if `nbcov'==0 {
if `dim'==1 {
local cov "1"
}
else if `dim'==2 {
local cov "1 1 0"
}
local nbcov:word count `cov'
}
if `nbcov'==1 {
if `cov'<0 {
di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option."
error 198
}
}
else if `nbcov'==3 {
local cov1:word 1 of `cov'
local cov2:word 2 of `cov'
local cov3:word 3 of `cov'
local rho=`cov3'/sqrt(`cov1'*`cov2')
if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 {
di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it."
error 198
exit
}
}
local nbmu:word count `mu'
if `nbmu'!=`dim'&`nbmu'!=0 {
di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')"
error 198
exit
}
local nbdisc:word count `disc'
if `nbdisc'!=`nbitems'&`nbdisc'!=0 {
di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmin:word count `pmin'
if `nbpmin'!=`nbitems'&`nbpmin'!=0 {
di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmax:word count `pmax'
if `nbpmax'!=`nbitems'&`nbpmax'!=0 {
di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbacc:word count `acc'
if `nbacc'!=`nbitems'&`nbacc'!=0 {
di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
preserve
tempfile saveraschbin
capture qui save `saveraschbin'
/********************************************************************************
PARAMETERS
********************************************************************************/
/*
scalar define hour=real(substr("$S_TIME",1,2))
scalar define min=real(substr("$S_TIME",4,2))
scalar define sec=real(substr("$S_TIME",7,2))
scalar define jour=real(substr("$S_DATE",1,2))
*/
local hour=real(substr("$S_TIME",1,2))
local min=real(substr("$S_TIME",4,2))
local sec=real(substr("$S_TIME",7,2))
local jour=real(substr("$S_DATE",1,2))
if "$seed"!="" {
global seed2=int($seed)
}
else {
global seed2=0
}
global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour'
if $seed>2^31-1 {
global seed=int($seed/10)
}
qui set seed $seed
if "`typediff'"=="uniform" {
if `dim'==1 {
if `nbdiff'==3 {
local min:word 2 of `diff'
local max:word 3 of `diff'
}
else if `nbdiff'==1 {
local min=-2
local max=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
}
local diff
forvalues i=1/`nbitems' {
local diff `diff' `=`min'+(`max'-`min')*`i'/(`nbitems'+1)'
}
}
if `dim'==2 {
if `nbdiff'==5 {
local min1:word 2 of `diff'
local max1:word 3 of `diff'
local min2:word 4 of `diff'
local max2:word 5 of `diff'
}
else if `nbdiff'==1 {
local min1=-2
local max1=2
local min2=-2
local max2=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
exit
}
local diff
forvalues i=1/`dim1' {
local diff `diff' `=`min1'+(`max1'-`min1')*`i'/(`dim1'+1)'
}
forvalues i=1/`dim2' {
local diff `diff' `=`min2'+(`max2'-`min2')*`i'/(`dim2'+1)'
}
}
}
if "`typediff'"=="gauss" {
if `dim'==1 {
if `nbdiff'==3 {
local mean:word 2 of `diff'
local var:word 3 of `diff'
}
else if `nbdiff'==1 {
local mean=0
local var=1
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues i=1/`nbitems' {
local tmp=invnorm(`i'/(`nbitems'+1))*sqrt(`var')+`mean'
local diff `diff' `tmp'
}
}
if `dim'==2 {
if `nbdiff'==5 {
local mean1:word 2 of `diff'
local var1:word 3 of `diff'
local mean2:word 4 of `diff'
local var2:word 5 of `diff'
}
else if `nbdiff'==1 {
local mean1=0
local var1=1
local mean2=0
local var2=1
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues i=1/`dim1' {
local tmp=invnorm(`i'/(`dim1'+1))*sqrt(`var1')+`mean1'
local diff `diff' `tmp'
}
forvalues i=1/`dim2' {
local tmp=invnorm(`i'/(`dim2'+1))*sqrt(`var2')+`mean2'
local diff `diff' `tmp'
}
}
}
tempname matmu matcov matdiff matdisc matpmin matpmax matacc
matrix define `matdiff'=J(`nbitems',1,0)
matrix define `matdisc'=J(`nbitems',1,0)
matrix define `matpmin'=J(`nbitems',1,0)
matrix define `matpmax'=J(`nbitems',1,0)
matrix define `matacc'=J(`nbitems',1,0)
matrix define `matmu'=J(`dim',1,0)
matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0)
forvalues i=1/`nbitems' {
local tmp:word `i' of `diff'
matrix `matdiff'[`i',1]=`tmp'
if `nbdisc'!=0 {
local tmp:word `i' of `disc'
matrix `matdisc'[`i',1]=`tmp'
}
else {
matrix `matdisc'[`i',1]=1
}
if `nbpmin'!=0 {
local tmp:word `i' of `pmin'
matrix `matpmin'[`i',1]=`tmp'
}
else {
matrix `matpmin'[`i',1]=0
}
if `nbpmax'!=0 {
local tmp:word `i' of `pmax'
matrix `matpmax'[`i',1]=`tmp'
}
else {
matrix `matpmax'[`i',1]=1
}
if `nbacc'!=0 {
local tmp:word `i' of `acc'
matrix `matacc'[`i',1]=`tmp'
}
else {
matrix `matacc'[`i',1]=1
}
}
if `nbcov'==3|`nbcov'==1 {
local tmp:word 1 of `cov'
matrix `matcov'[1,1]=`tmp'
if `nbcov'==3&`dim'==2 {
local tmp:word 2 of `cov'
matrix `matcov'[2,1]=`tmp'
local tmp:word 3 of `cov'
matrix `matcov'[3,1]=`tmp'
}
}
else {
matrix `matcov'[1,1]=1
if `dim'==2 {
matrix `matcov'[2,1]=1
matrix `matcov'[3,1]=0
}
}
if (`nbmu'==`dim') {
local tmp:word 1 of `mu'
matrix `matmu'[1,1]=`tmp'
if `dim'==2 {
local tmp:word 2 of `mu'
matrix `matmu'[2,1]=`tmp'
}
}
if `dim'==2 {
local corr=`matcov'[3,1]/sqrt(`matcov'[1,1]*`matcov'[2,1])
}
/********************************************************************************
ITEMS CHARACTERISTIC CURVES
********************************************************************************/
if "`draw'"!="" {
*set trace on
drop _all
qui set obs 2001
qui gen lt1=_n
qui replace lt1=(lt1-1001)/1000*4*sqrt(`cov')+`matmu'[1,1]
label variable lt1 "Latent trait"
local dess
forvalues i=1/`dim1' {
qui gen `prefix1'`i'=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt1-`matdiff'[`i',1]))))^(`matacc'[`i',1])
local dess `dess' (line `prefix'`i' lt1)
}
graph twoway `dess' , ylabel(0(.25)1) legend(off) ytitle("Probability of a positive response")
}
/********************************************************************************
SIMULATION
********************************************************************************/
drop _all
qui set obs `nbobs'
qui gen lt1=invnorm(uniform())
if `dim'==2 {
qui gen lt2=invnorm(uniform())
qui replace lt2=`corr'*lt1+sqrt(1-(`corr')^2)*lt2
qui replace lt2=lt2*sqrt(`matcov'[2,1])+`matmu'[2,1]
}
qui replace lt1=lt1*sqrt(`matcov'[1,1])+`matmu'[1,1]
if `dim'==1&`group'!=0 {
qui gen group=uniform()<`group'
qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1
qui replace lt1=lt1-`deltagroup'*`group' if group==0
}
di in gr "{hline 75}"
di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc"
di in gr "{hline 75}"
forvalues i=1/`dim1' {
qui gen `prefix1'`i'=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt1-`matdiff'[`i',1]))))^(`matacc'[`i',1])
qui replace `prefix1'`i'=uniform()<=`prefix1'`i'
di _col(1) in gr "`prefix1'`i'" _col(20) in ye %8.4f `matdiff'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
}
if `dim'==2 {
di in gr "{hline 75}"
forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' {
qui gen `prefix2'`=`i'-`dim1''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt2-`matdiff'[`i',1]))))^(`matacc'[`i',1])
qui replace `prefix2'`=`i'-`dim1''=uniform()<=`prefix2'`=`i'-`dim1''
di _col(1) in gr "`prefix2'`=`i'-`dim1''" _col(20) in ye %8.4f `matdiff'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
}
}
di in gr "{hline 75}"
di
qui corr lt*,cov
local var_1=r(Var_1)
return scalar var_1=r(Var_1)
if `dim'==2 {
local cov_12=r(cov_12)
local var_2=r(Var_2)
return scalar cov_12=r(cov_12)
return scalar var_2=r(Var_2)
qui corr lt*
local rho=r(rho)
return scalar rho=r(rho)
}
qui su lt1
local mean1=r(mean)
return scalar mean_1=r(mean)
if `dim'==2 {
qui su lt2
local mean2=r(mean)
return scalar mean_2=r(mean)
}
if `dim'==1&`group'!=0 {
qui su lt1 if group==0
local mean_0=r(mean)
qui su lt1 if group==1
local mean_1=r(mean)
local delta=`mean_1'-`mean_0'
}
return scalar nbobs=`nbobs'
di in gr "{hline 50}"
di _col(1) in gr "Latent trait" _c
if `dim'==2 {
di in gr "s"_c
}
di in gr _col(29) "Theorical" _col(42) "Observed"
di in gr "{hline 50}"
forvalues i=1/`dim' {
di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean`i''
di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',1] _col(42) %8.4f `var_`i''
}
if `dim'==1&`group'!=0 {
di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0'
di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1'
qui count if group==1
local prop=r(N)/`nbobs'
di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop'
}
if `dim'==2 {
di _col(1) in gr "Covariance" _col(30) in ye %8.4f `matcov'[3,1] _col(42) %8.4f `cov_12'
di _col(1) in gr "Correlation" _col(31) in ye %7.4f `corr' _col(43) %7.4f `rho'
}
di in gr "{hline 50}"
/********************************************************************************
CLEAR AND/OR STORE
********************************************************************************/
if "`clear'"!="" {
restore, not
preserve
}
if "`store'"!="" {
save "`store'",`replace'
}
if "`clear'"=="" {
use "`saveraschbin'",replace
}
end

View File

@ -0,0 +1,804 @@
*! version 3.5 May 16, 2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model,
* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM)
*
* Version 1 : May 9, 2005 (Jean-Benoit Hardouin)
* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/
* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/
* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/
* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/
* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/
* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/
* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/
* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/
* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/
* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/
* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/
* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/
*
* 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@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2005-2006, 2008-2009, 2011, 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 simirt , rclass
version 8.0
syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string)]
/********************************************************************************
TESTS
********************************************************************************/
if `group'<0|`group'>1 {
di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}"
error 198
exit
}
if "`clear'"==""&"`store'"=="" {
di in red "You must use at least one of these two options: clear and/or store."
error 198
exit
}
if "`dim'"!="" {
local nbdim:word count `dim'
if `nbdim'>2&"`covmatrix'"=="" {
di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it."
error 198
exit
}
if "`covmatrix'"!="" {
local nbrowcovm=rowsof(`covmatrix')
if `nbdim'!=`nbrowcovm' {
di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that."
error 198
exit
}
}
local nbitems=0
forvalues d=1/`nbdim' {
local dim`d':word `d' of `dim'
local nbitems=`nbitems'+`dim`d''
}
local dim=`nbdim'
if "`diff'"!="" {
local nbdiff:word count `diff'
local tmp:word 1 of `diff'
if "`tmp'"=="gauss"|"`tmp'"=="uniform" {
local typediff values
}
else if `nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
else if "`diff'"=="" {
local diff gauss
forvalues d=1/`dim' {
local diff `diff' 0 1
}
local typediff gauss
local nbdiff:word count `diff'
}
}
else if "`dim'"==""{
if "`diff'"==""&"`pcm'"=="" {
di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)."
error 198
exit
}
else if "`covmatrix'"!= "" {
local nbrowcovm=rowsof(`covmatrix')
if `nbrowcovm'>1 {
di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option."
error 198
exit
}
}
else if "`pcm'"!="" {
local nbitems=rowsof(`pcm')
local dim=1
local dim1=`nbitems'
}
else {
local nbdiff:word count `diff'
local nbitems=`nbdiff'
local dim=1
local dim1=`nbitems'
}
}
if (`group'!=0|`deltagroup'!=0)&`dim'!=1 {
di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data."
error 198
exit
}
if "`prefix'"=="" {
local prefix item
}
local nbprefix:word count `prefix'
if `nbprefix'!=`dim'&`nbprefix'!=1 {
di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it."
error 198
exit
}
if `nbprefix'==`dim' {
forvalues d=1/`dim' {
local prefix`d':word `d' of `prefix'
}
}
else {
forvalues d=1/`dim' {
local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
local prefix`d' `prefix'`tmp'
}
}
*set trace on
if "`covmatrix'"=="" {
local nbcov:word count `cov'
if `dim'==1&`nbcov'>1 {
di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option."
error 198
exit
}
else if `dim'==2&`nbcov'!=3&`nbcov'>0 {
di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)."
error 198
exit
}
else if `nbcov'==0 {
if `dim'==1 {
local cov "1"
}
else if `dim'==2 {
local cov "1 1 0"
}
local nbcov:word count `cov'
}
if `nbcov'==1 {
if `cov'<0 {
di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option."
error 198
}
}
else if `nbcov'==3 {
local cov1:word 1 of `cov'
local cov2:word 2 of `cov'
local cov3:word 3 of `cov'
local rho=`cov3'/sqrt(`cov1'*`cov2')
if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 {
di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it."
error 198
exit
}
}
tempname covmatrix2
if `dim'==1 {
matrix `covmatrix2'=(`cov')
}
else if `dim'==2 {
matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2')
}
local covmatrix `covmatrix2'
*matrix list `covmatrix2'
}
local nbmu:word count `mu'
if `nbmu'!=`dim'&`nbmu'!=0 {
di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')"
error 198
exit
}
local nbdisc:word count `disc'
if `nbdisc'!=`nbitems'&`nbdisc'!=0 {
di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmin:word count `pmin'
if `nbpmin'!=`nbitems'&`nbpmin'!=0 {
di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmax:word count `pmax'
if `nbpmax'!=`nbitems'&`nbpmax'!=0 {
di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbacc:word count `acc'
if `nbacc'!=`nbitems'&`nbacc'!=0 {
di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if "`rsm2'"!=""&`dim'==1 {
di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension"
error 198
exit
}
if "`id'"=="" {
local id="id"
}
preserve
tempfile saveraschbin
capture qui save `saveraschbin'
/********************************************************************************
PARAMETERS
********************************************************************************/
local hour=real(substr("$S_TIME",1,2))
local min=real(substr("$S_TIME",4,2))
local sec=real(substr("$S_TIME",7,2))
local jour=real(substr("$S_DATE",1,2))
if "$seed"!="" {
global seed2=int($seed)
}
else {
global seed2=0
}
global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour'
while $seed>2^31-1 {
global seed=int($seed/231)
}
qui set seed $seed
if "`typediff'"=="uniform" {
if `nbdiff'==`=`dim'*2+1' {
local min`d':word `=(`d'-1)*2+2' of `diff'
local max`d':word `=(`d'-1)*2+3' of `diff'
}
else if `nbdiff'==1 {
local min`d'=-2
local max`d'=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)'
}
}
}
*set trace on
if "`typediff'"=="gauss" {
if `nbdiff'==`=`dim'*2+1' {
forvalues d=1/`dim' {
local mean`d':word `=(`d'-1)*2+2' of `diff'
local var`d':word `=(`d'-1)*2+3' of `diff'
}
}
else if `nbdiff'==1 {
forvalues d=1/`dim' {
local mean`d'=0
local var`d'=1
}
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d''
local diff `diff' `tmp'
}
}
}
*set trace off
forvalues d=1/`dim' {
if "`rsm`d''"!="" {
local nbrsm`d':word count `rsm`d''
forvalues i=2/`=`nbrsm`d''+1' {
local rsm`d'`i':word `=`i'-1' of `rsm`d''
if "`threshold'"!=""&`rsm`d'`i''<0 {
di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive."
error 198
exit
}
}
}
}
if "`pcm'"!="" {
local nbmodas=colsof(`pcm')
forvalues j=1/`nbitems' {
local pcmpj`j'k0=-999999999999999
forvalues k=1/`nbmodas' {
local pcmpj`j'k`k'=`pcm'[`j',`k']
local tmp=`k'-1
if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' {
di in red "With the {hi:threshold} option, the difficulties of a given item must increase."
error 198
exit
}
}
}
}
tempname matmu matcov matdiff matdisc matpmin matpmax matacc
matrix define `matdiff'=J(`nbitems',1,0)
matrix define `matdisc'=J(`nbitems',1,0)
matrix define `matpmin'=J(`nbitems',1,0)
matrix define `matpmax'=J(`nbitems',1,0)
matrix define `matacc'=J(`nbitems',1,0)
matrix define `matmu'=J(`dim',1,0)
matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0)
if "`pcm'"=="" {
forvalues i=1/`nbitems' {
local tmp:word `i' of `diff'
matrix `matdiff'[`i',1]=`tmp'
if `nbdisc'!=0 {
local tmp:word `i' of `disc'
matrix `matdisc'[`i',1]=`tmp'
}
else {
matrix `matdisc'[`i',1]=1
}
if `nbpmin'!=0 {
local tmp:word `i' of `pmin'
matrix `matpmin'[`i',1]=`tmp'
}
else {
matrix `matpmin'[`i',1]=0
}
if `nbpmax'!=0 {
local tmp:word `i' of `pmax'
matrix `matpmax'[`i',1]=`tmp'
}
else {
matrix `matpmax'[`i',1]=1
}
if `nbacc'!=0 {
local tmp:word `i' of `acc'
matrix `matacc'[`i',1]=`tmp'
}
else {
matrix `matacc'[`i',1]=1
}
}
}
if "`covmatrix'"=="" {
if `nbcov'==3|`nbcov'==1 {
local tmp:word 1 of `cov'
matrix `matcov'[1,1]=`tmp'
if `nbcov'==3&`dim'==2 {
local tmp:word 2 of `cov'
matrix `matcov'[2,1]=`tmp'
local tmp:word 3 of `cov'
matrix `matcov'[3,1]=`tmp'
}
}
}
else if 6==9{
matrix `matcov'[1,1]=1
if `dim'==2 {
matrix `matcov'[2,1]=1
matrix `matcov'[3,1]=0
}
}
else if "`covmatrix'"!="" {
matrix `matcov'=`covmatrix'
}
if (`nbmu'==`dim') {
* local tmp:word 1 of `mu'
* matrix `matmu'[1,1]=`tmp'
forvalues d=1/`dim' {
local tmp:word `d' of `mu'
matrix `matmu'[`d',1]=`tmp'
}
* if `dim'>1 {
* local tmp:word 2 of `mu'
* matrix `matmu'[2,1]=`tmp'
* }
}
if `dim'==2 {
local corr=`matcov'[3,1]/sqrt(`matcov'[1,1]*`matcov'[2,1])
}
/********************************************************************************
ITEMS CHARACTERISTIC CURVES
********************************************************************************/
if "`draw'"!="" {
*set trace on
drop _all
qui set obs 2001
qui gen lt1=_n
qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1]
label variable lt1 "Latent trait"
local dess
if "`rsm1'"==""&"`pcm'"=="" {
if "`title'"=="" {
local title2="Item Characteristics Curves of the items"
}
else {
local title2="`title'"
}
forvalues i=1/`dim1' {
if "`threshold'"=="" {
qui gen `prefix1'`i'=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt1-`matdiff'[`i',1]))))^(`matacc'[`i',1])
}
else {
qui gen `prefix1'`i'=lt1>`matdiff'[`i',1]
}
local dess `dess' (line `prefix'`i' lt1)
}
graph twoway `dess' , ylabel(0(.25)1) legend(off) ytitle("Probability of a positive response" title"") title("`title2'")
}
else if "`pcm'"==""{
forvalues i=1/`dim1' {
if "`title'"=="" {
local title2="Item `i'"
}
else {
local title2="`title'"
}
local dess
local tau0=0
local tau1=`matdiff'[`i',1]
local D "1+exp(lt`d'-`tau1')"
forvalues k=2/`=`nbrsm1'+1' {
local tau`k'=`tau`=`k'-1''+`matdiff'[`i',1]+`rsm1`k''
local D "`D'+exp(`k'*lt1-`tau`k'') "
}
forvalues k=`=`nbrsm1'+1'(-1)0 {
tempname prob`k'
qui gen `prob`k''=exp(`k'*lt1-`tau`k'')/(`D')
local dess `dess' (line `prob`k'' lt1)
label variable `prob`k'' "`k'"
}
graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace)
}
}
else if "`pcm'"!=""{
forvalues j=1/`dim1' {
if "`title'"=="" {
local title2="Item `j'"
}
else {
local title2="`title'"
}
local dess
local tauj`j'k0=0
forvalues k=1/`nbmodas' {
local tauj`j'k`k'=`tauj`j'k`=`k'-1''+`matdiff'[`j',`k']
local D "`D'+exp(`k'*lt1-`tauj`j'k`k'') "
}
forvalues k=`=`nbrsm1'+1'(-1)0 {
tempname prob`k'
qui gen `prob`k''=exp(`k'*lt1-`tauj`j'k`k'')/(`D')
local dess `dess' (line `prob`k'' lt1)
label variable `prob`k'' "`k'"
}
graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace)
}
}
}
/********************************************************************************
SIMULATION
********************************************************************************/
drop _all
qui set obs `nbobs'
gen `id'=_n
local names
forvalues d=1/`dim' {
qui gen x`d'=invnorm(uniform())
qui compress
local names `names' lt`d'
}
/*mkmat lt1-lt`dim' , matrix(lt)
matrix Chol=cholesky(corr(`covmatrix'))
*matrix list lt
*matrix list Chol
matrix lt=lt*Chol'
matrix colnames lt=`names'
*matrix list lt
drop _all
qui svmat lt*/
matrix Chol=cholesky(corr(`covmatrix'))
forvalues d=1/`dim' {
qui gen lt`d'=0
forvalues i=1/`d' {
qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i'
}
qui compress
}
qui drop x*
forvalues d=1/`dim' {
qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1]
qui compress
}
if `dim'==1&`group'!=0 {
if "`random'"=="" {
qui gen group=uniform()<`group'
}
else {
qui gen group=`id'<=`group'*`nbobs'
}
qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1
qui replace lt1=lt1-`deltagroup'*`group' if group==0
qui compress
}
di in gr "Number of individuals: " in ye `nbobs'
di
if "`threshold'"==""&"`rsm1'"=="" {
local line di in gr "{hline 75}"
}
else {
local line di in gr "{hline 27}"
}
if "`threshold'"==""&"`rsm1'"==""&"`pcm'"=="" {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc"
}
else {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty"
}
local dim0=0
*set trace on
local deb1=1
local fin1=`dim1'
forvalues d=1/`dim' { /* FOREACH DIMENSION*/
local deb`d'=`fin`=`d'-1''+1
local fin`d'=`deb`d''+`dim`d''-1
`line'
local p=`d'-1
local q=1
forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/
*set trace on
*local q=`i'-`dim`p''*/
qui compress
if "`pcm'"=="" {
tempname prob`=`nbrsm`d''+2'
qui gen `prob`=`nbrsm`d''+2''=0
local tau1=`matdiff'[`i',1]
local D "1+exp(lt`d'-`tau1')"
forvalues k=2/`=`nbrsm`d''+1' {
local tau`k'=`tau`=`k'-1''+`matdiff'[`i',1]+`rsm`d'`k''
*di "tau`k'=`tau`k''"
local D "`D'+exp(`k'*lt`d'-`tau`k'') "
}
}
else {
tempname prob`=`nbmodas'+1'
qui gen `prob`=`nbmodas'+1''=0
local tau1=`pcm'[`i',1]
local D "1+exp(lt`d'-`tau1')"
forvalues k=2/`nbmodas' {
local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k']
*di "tau`k'=`tau`k''"
local D "`D'+exp(`k'*lt`d'-`tau`k'') "
}
}
if "`threshold'"==""/*&"`rsm1'"==""*/ {
if "`rsm`d''"==""&"`pcm'"=="" {
tempname prob1
qui gen `prob1'=`prob`=`nbrsm`d''+2''+`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(1/(1+exp(-`matdisc'[`i',1]*(lt`d'-`matdiff'[`i',1]))))^(`matacc'[`i',1])
qui compress
}
else if "`rsm`d''"!=""{
forvalues k=`=`nbrsm`d''+1'(-1)1 {
tempname prob`k'
qui gen `prob`k''=exp(`k'*lt`d'-`tau`k'')/(`D')+`prob`=`k'+1''
qui compress
}
}
else if "`pcm'"!="" {
forvalues k=`nbmodas'(-1)1 {
tempname prob`k'
qui gen `prob`k''=exp(`k'*lt`d'-`tau`k'')/(`D')+`prob`=`k'+1''
qui compress
}
}
qui gen `prefix`d''`q'=0
if "`rsm1'"==""&"`pcm'"=="" {
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `matdiff'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
}
else if "`rsm1'"!="" {
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `matdiff'[`i',1]
}
else if "`pcm'"!="" {
forvalues k=1/`nbmodas' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
}
}
tempname uni
qui gen `uni'=uniform()
qui compress
if "`pcm'"=="" {
forvalues k=1/`=`nbrsm`d''+1' {
qui replace `prefix`d''`q'=`k' if `uni'<=`prob`k''
qui drop `prob`k''
qui compress
}
}
else {
forvalues k=1/`nbmodas' {
qui replace `prefix`d''`q'=`k' if `uni'<=`prob`k''
qui drop `prob`k''
qui compress
}
}
}
else { /*if "`threshold'"!=""*/
if "`pcm'"=="" {
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `matdiff'[`i',1]
qui gen `prefix`d''`q'=lt`d'>`matdiff'[`i',1]
qui compress
forvalues k=1/`=`nbrsm`d''+1' {
qui replace `prefix`d''`q'=`k' if lt`d'>=`tau`k''
qui compress
}
}
else {
qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1]
forvalues k=1/`nbmodas' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
qui replace `prefix`d''`q'=`k' if lt`d'>`pcm'[`i',`k']
qui compress
}
}
}
local q=`q'+1
}
forvalues k=2/`=`nbrsm`d''+1' {
di _col(1) in gr "tau`k'" _col(20) in ye %8.4f `rsm`d'`k''
}
}
`line'
di
*set trace on
forvalues d=1/`dim' {
qui su lt`d'
local var_`d'=r(Var)
local mean_`d'=r(mean)
forvalues l=`=`d'+1'/`dim' {
qui corr lt`d' lt`l' ,cov
local cov_`d'_`l'=r(cov_12)
return scalar cov_`d'_`l'=`cov_`d'_`l''
}
return scalar mean_`d'=`mean_`d''
return scalar var_`d'=`var_`d''
}
forvalues d=1/`dim' {
forvalues l=`=`d'+1'/`dim' {
local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'')
return scalar corr_`d'_`l'=`corr_`d'_`l''
}
}
if `dim'==1&`group'!=0 {
qui su lt1 if group==0
local mean_0=r(mean)
qui su lt1 if group==1
local mean_1=r(mean)
local delta=`mean_1'-`mean_0'
}
return scalar nbobs=`nbobs'
tempname matcorr
*matrix list `matcov'
matrix `matcorr'=corr(`matcov')
di in gr "{hline 50}"
di _col(1) in gr "Latent trait" _c
if `dim'==2 {
di in gr "s"_c
}
di in gr _col(30) "Expected" _col(42) "Observed"
di in gr "{hline 50}"
forvalues i=1/`dim' {
di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i''
di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i''
forvalues d=`=`i'+1'/`dim' {
di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d''
di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d''
}
di in gr "{hline 50}"
}
if `dim'==1&`group'!=0 {
di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0'
di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1'
qui count if group==1
local prop=r(N)/`nbobs'
di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop'
di in gr "{hline 50}"
}
/********************************************************************************
CLEAR AND/OR STORE
********************************************************************************/
qui compress
if "`clear'"!="" {
restore, not
preserve
}
if "`store'"!="" {
save "`store'",`replace'
}
if "`clear'"=="" {
use "`saveraschbin'",replace
}
end

View File

@ -0,0 +1,71 @@
program define simul2tl2plm
version 7.0
syntax [, nbobs(integer 2000) dim1(real 7) dim2(real 7) corr(real 0) disc1(real 1) disc2(real 1) sigma1(real 1) sigma2(real 1)]
scalar define hour=real(substr("$S_TIME",1,2))
scalar define min=real(substr("$S_TIME",4,2))
scalar define sec=real(substr("$S_TIME",7,2))
scalar define jour=real(substr("$S_DATE",1,2))
if "$seed2"!="" {
global seed2=int($seed/100000)}
else {
global seed2=0
}
global seed=sec*1000000+min*10000+hour*100+jour+$seed2
set seed $seed
quietly {
drop _all
set obs `nbobs'
gen TL1=invnorm(uniform())*`sigma1'
gen TL2=invnorm(uniform())*`sigma2'
replace TL2=`corr'*TL1+sqrt(1-`corr'^2)*TL2
local items=1
global rep1
while `items'<=`dim1' {
local nitems=100+`items'
gen diff`nitems'=invnorm(`items'/(`dim1'+1))
gen prob`nitems'=1/(1+exp(-1.7*`disc1'*(TL1-diff`nitems')))
gen rep`nitems'=0
replace rep`nitems'=1 if prob`nitems'>=uniform()
global rep1 $rep1 rep`nitems'
local items=`items'+1
}
local items=1
global rep2
while `items'<=`dim2' {
local nitems=200+`items'
gen diff`nitems'=invnorm(`items'/(`dim2'+1))
gen prob`nitems'=1/(1+exp(-1.7*`disc2'*(TL2-diff`nitems')))
gen rep`nitems'=0
replace rep`nitems'=1 if prob`nitems'>=uniform()
global rep2 $rep2 rep`nitems'
local items=`items'+1
}
gen ind=_n
keep ind $rep1 $rep2}
quietly{
reshape long rep,i(ind) j(item)
local items=1
while `items'<=`dim1' {
local nitems=100+`items'
gen item`nitems'=0
replace item`nitems'=-1 if item==`nitems'
local items=`items'+1
}
local items=1
while `items'<=`dim2' {
local nitems=200+`items'
gen item`nitems'=0
replace item`nitems'=-1 if item==`nitems'
local items=`items'+1
}
}/*fin du quietly*/
end

View File

@ -0,0 +1,10 @@
program define sascfa,eclass
version 11.0
syntax anything [if] [in] ,partition(numlist) varname(string) lisrel(string) [batch]
preserve
*%macro CFA (dataset= , listeItems= , partition= , varname= , lisrel=);
tosas `if' `in' , pgm(%include 'C:\ado\macros SAS\MACRO cfa.sas';%CFA(dataset=stata,listeItems=`anything', partition=`partition', varname=`varname',lisrel=`lisrel');) `batch'
end

View File

@ -0,0 +1,69 @@
program define senspescore, rclass
version 8
syntax varlist(min=1 max=1 numeric) [, Group(varname) Threshold(string) INVerse]
tempfile senspescorefile
qui save `senspescorefile', replace
qui sort `group'
tempname p0 p1 n0 n1 q0
qui count
local nind=r(N)
qui gen `n0'=.
qui gen `n1'=.
qui gen `p0'=.
qui gen `p1'=.
local l0=0
local l1=1
if "`inverse'"=="" {
local m0="<"
local m1=">"
}
else {
local m0=">"
local m1="<"
}
qui count if `group'==`l0'
local group0=r(N)
qui count if `group'==`l1'
local group1=r(N)
forvalues i=1/`nind' {
qui count if `varlist'`m0'`varlist'[`i']&`group'==`l0'
qui replace `n0'=`r(N)' in `i'
qui count if `varlist'`m1'`varlist'[`i']&`group'==`l1'
qui replace `n1'=`r(N)' in `i'
qui replace `p1'=`n`l1''/`group`l1'' in `i'
qui replace `p0'=`n`l0''/`group`l0'' in `i'
}
tempname diff min
if "`threshold'"!="" {
qui gen `diff'=abs(`varlist'-`threshold')
qui sort `diff'
qui gen `min'=1 in 1
}
sort `varlist'
label variable `n0' "N bien class<73>es groupe `l0'"
label variable `n1' "N bien class<73>es groupe `l1'"
label variable `p0' "Specificity"
label variable `p1' "Sensibility"
twoway line `n0' `n1' `varlist',name(n,replace) xline(`threshold')
twoway line `p0' `p1' `varlist',name(p,replace) xline(`threshold')
qui gen `q0'=1-`p0'
label variable `q0' "1-Specificity"
local scatter
if "`threshold'"!="" {
local scatter "(scatter `p1' `q0' if `min'==1)"
}
twoway (line `p1' `q0') (line `q0' `q0') `scatter' ,name(roc,replace) legend(off)
use `senspescorefile', clear
end

View File

@ -0,0 +1,585 @@
*! Version 1.6 23August2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : sf36fr
* computes score of the French SF36 questionnnaire
*
* Historic :
* Version 1 (May 2, 2013) [Jean-Benoit Hardouin]
* Release 1 : May 2, 2013 [Jean-benoit Hardouin]
* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/
* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/
* Release 1.5 : July 29, 2019 [Jean-Benoit Hardouin] /*radar option*/
* Release 1.6 : August 23, 2019 [Jean-Benoit Hardouin] /*correction of a bug to save the scores*/
*
* Jean-benoit Hardouin, phD, Assistant Professor
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program :http://www.anaqol.org
*
* Copyright 2013, 2018, 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
*
***********************************************************************************************************
program define sf36fr , rclass
version 8.2
syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string) RADar FILESave DIRSave(string)]
*preserve
local nbitems : word count `varlist'
if `nbitems'!=36 {
di in red "There is `nbitems' items defined instead of 36"
}
tokenize `varlist'
local varlistsav `varlist'
local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5
local sf2
local varlist2
forvalues i=1/36 {
local j:word `i' of `sf'
tempname `j'
*di " qui gen `j'=``i''"
qui gen ``j''=``i''
local varlist2 "`varlist2' ``j''"
}
local varlist "`varlist2'"
tokenize `varlist'
*di "`varlist'"
if "`v2'"=="" {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5
}
else {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
}
forvalues i=1/36 {
local mod`i':word `i' of `modamax'
}
local error=0
local inf
local sup
local c=1
foreach i of varlist `varlist' {
qui count if `i'<1
if `r(N)'>0 {
local error=1
local inf "`inf' `i'"
}
local tmp: word `c' of `modamax'
qui count if `i'>`c'
if `r(N)'>0 {
local error=1
local inf "`sup' `i'"
}
local ++c
}
forvalues i=1/15 {
tempname inc`i'
}
local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21
local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22
*tab `11' `3'
qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=.
* tab `inc`i''
qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=.
qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=.
qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=.
qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=.
qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=.
qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=.
qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=.
qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=.
qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=.
qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=.
qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=.
qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=.
qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=.
qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=.
tempname scoreinc
genscore `inc1'-`inc15',score(`scoreinc')
if "`details'" !="" {
di "{hline 80}"
di in gr "Discrepancies" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals"
di "{hline 80}"
*di "varlist:`varlistsav'"
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
local ni1:word `i1' of `varlistsav'
local ni2:word `i2' of `varlistsav'
qui count if `inc`i''==1
di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)'
}
di "{hline 80}"
}
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
qui replace ``i1''=. if `inc`i''==1
qui replace ``i2''=. if `inc`i''==1
}
tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh
/*PF*/
imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp')
genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf')
qui replace `scorepf'=(`scorepf'-10)/20*100
/*RP*/
imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp')
genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp')
qui replace `scorerp'=(`scorerp'-4)/4*100
/*BP*/
tempvar jb
qui gen `jb'=.
qui replace `jb'=6 if `21'==1&`22'==1
qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1
qui replace `jb'=4 if `22'==2&`21'!=.
qui replace `jb'=3 if `22'==3&`21'!=.
qui replace `jb'=2 if `22'==4&`21'!=.
qui replace `jb'=1 if `22'==5&`21'!=.
qui replace `jb'=6 if `22'==1&`21'==.
qui replace `jb'=4.75 if `22'==2&`21'==.
qui replace `jb'=3.5 if `22'==3&`21'==.
qui replace `jb'=2.25 if `22'==4&`21'==.
qui replace `jb'=1 if `22'==5&`21'==.
qui replace `22'=`jb'
if "`v2'"=="" {
qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1
}
else {
qui recode `21' 1=6 2=4.8 3=2.65 4=1
}
imputeitems `21' `22',max(0) noround prefix(`imp')
* replace `imp'`21'=`21'
* replace `imp'`22'=`22'
qui genscore `imp'`21' `imp'`22',score(`scorebp')
* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp'
qui replace `scorebp'=(`scorebp'-2)/10*100
*tab `scorebp'
/*GH*/
qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1
qui recode `34' 1=5 2=4 3=3 4=2 5=1
qui recode `36' 1=5 2=4 3=3 4=2 5=1
imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp')
genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh')
qui replace `scoregh'=(`scoregh'-5)/20*100
/*VT*/
if "`v2'"=="" {
qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp')
genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt')
qui replace `scorevt'=(`scorevt'-4)/20*100
/*SF*/
if "`v2'"=="" {
qui recode `20' 1=5 2=4 3=3 4=2 5=1
}
else {
qui recode `20' 1=5 2=4 3=2.5 4=1
}
imputeitems `20' `32',max(0) noround prefix(`imp')
genscore `imp'`20' `imp'`32',score(`scoresf')
qui replace `scoresf'=(`scoresf'-2)/8*100
/*RE*/
imputeitems `17' `18' `19',max(1) noround prefix(`imp')
genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere')
qui replace `scorere'=(`scorere'-3)/3*100
/*MH*/
if "`v2'"=="" {
qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp')
genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh')
qui replace `scoremh'=(`scoremh'-5)/25*100
tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs
/*scores composites*/
qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490
qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729
qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879
qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964
qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942
qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649
qui gen `scorerez'=(`scorere'-81.29467)/33.02717
qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189
qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50
qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50
/*scores composites SF12*/
tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c
tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c
qui gen `sf12p_1'=`1'
qui gen `sf12p_2a'=`4'
qui gen `sf12p_2b'=`6'
qui gen `sf12p_3a'=`14'
qui gen `sf12p_3b'=`15'
qui gen `sf12p_4a'=`18'
qui gen `sf12p_4b'=`19'
qui gen `sf12p_5'=`20'
qui gen `sf12p_6'=`32'
qui gen `sf12p_7a'=`26'
qui gen `sf12p_7b'=`27'
qui gen `sf12p_7c'=`28'
qui gen `sf12m_1'=`1'
qui gen `sf12m_2a'=`4'
qui gen `sf12m_2b'=`6'
qui gen `sf12m_3a'=`14'
qui gen `sf12m_3b'=`15'
qui gen `sf12m_4a'=`18'
qui gen `sf12m_4b'=`19'
qui gen `sf12m_5'=`20'
qui gen `sf12m_6'=`32'
qui gen `sf12m_7a'=`26'
qui gen `sf12m_7b'=`27'
qui gen `sf12m_7c'=`28'
qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399
qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175
qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0
qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0
qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0
qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0
qui recode `sf12p_3a' 1=-4.61617 2=0
qui recode `sf12m_3a' 1=1.44060 2=0
qui recode `sf12p_3b' 1=-5.51747 2=0
qui recode `sf12m_3b' 1=1.66968 2=0
qui recode `sf12p_4a' 1=3.04365 2=0
qui recode `sf12m_4a' 1=-6.82672 2=0
qui recode `sf12p_4b' 1=2.32091 2=0
qui recode `sf12m_4b' 1=-5.69921 2=0
qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0
qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0
if "`v2'"=="" {
qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619
qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0
}
else {
qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619
qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0
}
qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706
qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781
if "`save'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `save'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0 {
qui replace `save'`i'=`score`i''
}
else {
qui gen `save'`i'=`score`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv
matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24)
matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63)
matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29)
matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96)
matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03)
matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98)
matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04)
matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99)
tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh
tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv
if "`age'"!=""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75
qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75
qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75
qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75
local ++c
}
}
else if "`age'"!=""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75
qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75
local ++c
}
}
else if "`age'"==""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1
qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0
qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1
qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0
local ++c
}
}
else if "`age'"==""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
gen `scoreref`i''=`scoreref'[1,`c']
gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2
local ++c
}
}
tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs
tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv
qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490
qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729
qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879
qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964
qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942
qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649
qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717
qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189
qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50
qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50
qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2
qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2
qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2
qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2
qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2
qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2
qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2
qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2
qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2
qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2
if "`saveref'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `saveref'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0 {
qui replace `saveref'`i'=`scoreref`i''
}
else {
qui gen `saveref'`i'=`scoreref`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
if "`details'"!=""|"`radar'"!="" {
tempname radar
qui matrix `radar'=J(12,2,.)
if "`details'"!="" {
di "{hline 80}"
di in gr _col(12) "Sample" _col(51) "Reference"
di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p"
di "{hline 80}"
}
local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m
local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
qui su `score`i''
local means`i'=r(mean)
local sds`i'=r(sd)
local mins`i'=r(min)
local maxs`i'=r(max)
local n`i'=r(N)
matrix `radar'[`c',1]=`means`i''
qui su `scoreref`i''
matrix `radar'[`c',2]=r(mean)
if "`i'"!="sf12p"&"`i'"!="sf12m" {
qui su `scoreref`i'' if `score`i''!=.
local meanr`i'=r(mean)
local sdr`i'=r(sd)
local vr`i'=(`sdr`i'')^2
qui su `scoreref`i'v' if `score`i''!=.
local meanvr`i'=r(mean)
local sdr`i'=sqrt(`vr`i''+`meanvr`i'')
*local minr`i'=r(min)
*local maxr`i'=r(max)
qui ttest `score`i''=`meanr`i''
local p`i'=r(p)
}
if "`details'"!="" {
di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i''
}
local ++c
}
if "`details'"!="" {
di "{hline 80}"
}
*corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m'
*scatter `scorepcs' `scoresf12p' ,name(p)
*scatter `scoremcs' `scoresf12m' ,name(m)
*su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c'
*su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c'
if "`radar'"!=""&"`v2'"=="" {
qui tempfile radarfile
qui save `radarfile', replace
qui drop _all
qui svmat `radar'
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local c=1
qui gen name=""
foreach i in `listmin' {
qui replace name="`i'" in `c'
local ++c
}
qui rename `radar'1 scoreSF36
rename `radar'2 scoreSF36ref
qui keep in 1/10
label variable scoreSF36 "Sample"
label variable scoreSF36ref "General French population"
if "`filesave'"!="" {
if "`dirsave'"=="" {
local dirsave `c(pwd)'
}
local saving "saving(`dirsave'//radar, replace) "
}
qui radar name scoreSF36 scoreSF36ref, note("") title("Comparison of the sample with the general French population") legend(lab(1 "Sample") lab(2 "General French population")) `saving'
qui use `radarfile', clear
}
}
if "`saveimp'"!="" {
*su
foreach i of numlist 1 3/36 {
local j:word `i' of `varlistsav'
*di "gen `saveimp'`j'=`imp'``i''"
capture confirm variable `saveimp'`j'
if _rc==0&"`replace'"=="" {
di in ye "The variable `saveimp'`j' already exists and cannot be replaced."
}
else if _rc==0&"`replace'"!="" {
qui replace `saveimp'`j'=`imp'``i''
}
else {
qui gen `saveimp'`j'=`imp'``i''
}
}
}
*restore, preserve
end

View File

@ -0,0 +1,588 @@
*! Version 1.7 29August2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : sf36fr
* computes score of the French SF36 questionnnaire
*
* Historic :
* Version 1 (May 2, 2013) [Jean-Benoit Hardouin]
* Release 1 : May 2, 2013 [Jean-benoit Hardouin]
* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/
* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/
* Release 1.5 : July 29, 2019 [Jean-Benoit Hardouin] /*radar option*/
* Release 1.6 : August 23, 2019 [Jean-Benoit Hardouin] /*correction of a bug to save the scores*/
* Release 1.7 : August 29, 2019 [Jean-Benoit Hardouin] /*improvement of radar*/
*
* Jean-benoit Hardouin, phD, Assistant Professor
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program :http://www.anaqol.org
*
* Copyright 2013, 2018, 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
*
***********************************************************************************************************
program define sf36fr , rclass
version 8.2
syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string) RADar FILESave DIRSave(string)]
*preserve
local nbitems : word count `varlist'
if `nbitems'!=36 {
di in red "There is `nbitems' items defined instead of 36"
}
tokenize `varlist'
local varlistsav `varlist'
local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5
local sf2
local varlist2
forvalues i=1/36 {
local j:word `i' of `sf'
tempname `j'
*di " qui gen `j'=``i''"
qui gen ``j''=``i''
local varlist2 "`varlist2' ``j''"
}
local varlist "`varlist2'"
tokenize `varlist'
*di "`varlist'"
if "`v2'"=="" {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5
}
else {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
}
forvalues i=1/36 {
local mod`i':word `i' of `modamax'
}
local error=0
local inf
local sup
local c=1
foreach i of varlist `varlist' {
qui count if `i'<1
if `r(N)'>0 {
local error=1
local inf "`inf' `i'"
}
local tmp: word `c' of `modamax'
qui count if `i'>`c'
if `r(N)'>0 {
local error=1
local inf "`sup' `i'"
}
local ++c
}
forvalues i=1/15 {
tempname inc`i'
}
local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21
local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22
*tab `11' `3'
qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=.
* tab `inc`i''
qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=.
qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=.
qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=.
qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=.
qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=.
qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=.
qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=.
qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=.
qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=.
qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=.
qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=.
qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=.
qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=.
qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=.
tempname scoreinc
genscore `inc1'-`inc15',score(`scoreinc')
if "`details'" !="" {
di "{hline 80}"
di in gr "Discrepancies" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals"
di "{hline 80}"
*di "varlist:`varlistsav'"
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
local ni1:word `i1' of `varlistsav'
local ni2:word `i2' of `varlistsav'
qui count if `inc`i''==1
di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)'
}
di "{hline 80}"
}
*list subjid `scoreinc' `inc1'-`inc15' `scoreinc' if `scoreinc'!=0&`scoreinc'!=.
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
qui replace ``i1''=. if `inc`i''==1
qui replace ``i2''=. if `inc`i''==1
}
tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh
/*PF*/
imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp')
genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf')
qui replace `scorepf'=(`scorepf'-10)/20*100
/*RP*/
imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp')
genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp')
qui replace `scorerp'=(`scorerp'-4)/4*100
/*BP*/
tempvar jb
qui gen `jb'=.
qui replace `jb'=6 if `21'==1&`22'==1
qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1
qui replace `jb'=4 if `22'==2&`21'!=.
qui replace `jb'=3 if `22'==3&`21'!=.
qui replace `jb'=2 if `22'==4&`21'!=.
qui replace `jb'=1 if `22'==5&`21'!=.
qui replace `jb'=6 if `22'==1&`21'==.
qui replace `jb'=4.75 if `22'==2&`21'==.
qui replace `jb'=3.5 if `22'==3&`21'==.
qui replace `jb'=2.25 if `22'==4&`21'==.
qui replace `jb'=1 if `22'==5&`21'==.
qui replace `22'=`jb'
if "`v2'"=="" {
qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1
}
else {
qui recode `21' 1=6 2=4.8 3=2.65 4=1
}
imputeitems `21' `22',max(0) noround prefix(`imp')
* replace `imp'`21'=`21'
* replace `imp'`22'=`22'
qui genscore `imp'`21' `imp'`22',score(`scorebp')
* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp'
qui replace `scorebp'=(`scorebp'-2)/10*100
*tab `scorebp'
/*GH*/
qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1
qui recode `34' 1=5 2=4 3=3 4=2 5=1
qui recode `36' 1=5 2=4 3=3 4=2 5=1
imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp')
genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh')
qui replace `scoregh'=(`scoregh'-5)/20*100
/*VT*/
if "`v2'"=="" {
qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp')
genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt')
qui replace `scorevt'=(`scorevt'-4)/20*100
/*SF*/
if "`v2'"=="" {
qui recode `20' 1=5 2=4 3=3 4=2 5=1
}
else {
qui recode `20' 1=5 2=4 3=2.5 4=1
}
imputeitems `20' `32',max(0) noround prefix(`imp')
genscore `imp'`20' `imp'`32',score(`scoresf')
qui replace `scoresf'=(`scoresf'-2)/8*100
/*RE*/
imputeitems `17' `18' `19',max(1) noround prefix(`imp')
genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere')
qui replace `scorere'=(`scorere'-3)/3*100
/*MH*/
if "`v2'"=="" {
qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp')
genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh')
qui replace `scoremh'=(`scoremh'-5)/25*100
tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs
/*scores composites*/
qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490
qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729
qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879
qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964
qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942
qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649
qui gen `scorerez'=(`scorere'-81.29467)/33.02717
qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189
qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50
qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50
/*scores composites SF12*/
tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c
tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c
qui gen `sf12p_1'=`1'
qui gen `sf12p_2a'=`4'
qui gen `sf12p_2b'=`6'
qui gen `sf12p_3a'=`14'
qui gen `sf12p_3b'=`15'
qui gen `sf12p_4a'=`18'
qui gen `sf12p_4b'=`19'
qui gen `sf12p_5'=`20'
qui gen `sf12p_6'=`32'
qui gen `sf12p_7a'=`26'
qui gen `sf12p_7b'=`27'
qui gen `sf12p_7c'=`28'
qui gen `sf12m_1'=`1'
qui gen `sf12m_2a'=`4'
qui gen `sf12m_2b'=`6'
qui gen `sf12m_3a'=`14'
qui gen `sf12m_3b'=`15'
qui gen `sf12m_4a'=`18'
qui gen `sf12m_4b'=`19'
qui gen `sf12m_5'=`20'
qui gen `sf12m_6'=`32'
qui gen `sf12m_7a'=`26'
qui gen `sf12m_7b'=`27'
qui gen `sf12m_7c'=`28'
qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399
qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175
qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0
qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0
qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0
qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0
qui recode `sf12p_3a' 1=-4.61617 2=0
qui recode `sf12m_3a' 1=1.44060 2=0
qui recode `sf12p_3b' 1=-5.51747 2=0
qui recode `sf12m_3b' 1=1.66968 2=0
qui recode `sf12p_4a' 1=3.04365 2=0
qui recode `sf12m_4a' 1=-6.82672 2=0
qui recode `sf12p_4b' 1=2.32091 2=0
qui recode `sf12m_4b' 1=-5.69921 2=0
qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0
qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0
if "`v2'"=="" {
qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619
qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0
}
else {
qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619
qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0
}
qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706
qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781
if "`save'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `save'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0 {
qui replace `save'`i'=`score`i''
}
else {
qui gen `save'`i'=`score`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv
matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24)
matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63)
matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29)
matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96)
matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03)
matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98)
matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04)
matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99)
tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh
tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv
if "`age'"!=""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75
qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75
qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75
qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75
local ++c
}
}
else if "`age'"!=""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75
qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75
local ++c
}
}
else if "`age'"==""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1
qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0
qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1
qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0
local ++c
}
}
else if "`age'"==""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
gen `scoreref`i''=`scoreref'[1,`c']
gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2
local ++c
}
}
tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs
tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv
qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490
qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729
qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879
qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964
qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942
qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649
qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717
qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189
qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50
qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50
qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2
qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2
qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2
qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2
qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2
qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2
qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2
qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2
qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2
qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2
if "`saveref'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `saveref'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0 {
qui replace `saveref'`i'=`scoreref`i''
}
else {
qui gen `saveref'`i'=`scoreref`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
if "`details'"!=""|"`radar'"!="" {
tempname radar
qui matrix `radar'=J(12,2,.)
if "`details'"!="" {
di "{hline 80}"
di in gr _col(12) "Sample" _col(51) "Reference"
di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p"
di "{hline 80}"
}
local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m
local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
qui su `score`i''
local means`i'=r(mean)
local sds`i'=r(sd)
local mins`i'=r(min)
local maxs`i'=r(max)
local n`i'=r(N)
matrix `radar'[`c',1]=`means`i''
qui su `scoreref`i''
matrix `radar'[`c',2]=r(mean)
if "`i'"!="sf12p"&"`i'"!="sf12m" {
qui su `scoreref`i'' if `score`i''!=.
local meanr`i'=r(mean)
local sdr`i'=r(sd)
local vr`i'=(`sdr`i'')^2
qui su `scoreref`i'v' if `score`i''!=.
local meanvr`i'=r(mean)
local sdr`i'=sqrt(`vr`i''+`meanvr`i'')
*local minr`i'=r(min)
*local maxr`i'=r(max)
qui ttest `score`i''=`meanr`i''
local p`i'=r(p)
}
if "`details'"!="" {
di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i''
}
local ++c
}
if "`details'"!="" {
di "{hline 80}"
}
*corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m'
*scatter `scorepcs' `scoresf12p' ,name(p)
*scatter `scoremcs' `scoresf12m' ,name(m)
*su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c'
*su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c'
if "`radar'"!=""&"`v2'"=="" {
qui tempfile radarfile
qui save `radarfile', replace
qui drop _all
qui svmat `radar'
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local c=1
qui gen name=""
foreach i in `listmin' {
qui replace name="`i'" in `c'
local ++c
}
qui rename `radar'1 scoreSF36
rename `radar'2 scoreSF36ref
qui keep in 1/10
label variable scoreSF36 "Sample"
label variable scoreSF36ref "General French population"
if "`filesave'"!="" {
if "`dirsave'"=="" {
local dirsave `c(pwd)'
}
local saving "saving(`dirsave'//radar, replace) "
}
qui radar name scoreSF36 scoreSF36ref, note("") title("Comparison of the sample with the general French population") legend(lab(1 "Sample") lab(2 "General French population")) `saving' r(0 20 40 60 80 100)
qui use `radarfile', clear
}
}
if "`saveimp'"!="" {
*su
foreach i of numlist 1 3/36 {
local j:word `i' of `varlistsav'
*di "gen `saveimp'`j'=`imp'``i''"
capture confirm variable `saveimp'`j'
if _rc==0&"`replace'"=="" {
di in ye "The variable `saveimp'`j' already exists and cannot be replaced."
}
else if _rc==0&"`replace'"!="" {
qui replace `saveimp'`j'=`imp'``i''
}
else {
qui gen `saveimp'`j'=`imp'``i''
}
}
}
*restore, preserve
end

View File

@ -0,0 +1,589 @@
*! Version 1.8 13December2023
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : sf36fr
* computes score of the French SF36 questionnnaire
*
* Historic :
* Version 1 (May 2, 2013) [Jean-Benoit Hardouin]
* Release 1 : May 2, 2013 [Jean-benoit Hardouin]
* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/
* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/
* Release 1.5 : July 29, 2019 [Jean-Benoit Hardouin] /*radar option*/
* Release 1.6 : August 23, 2019 [Jean-Benoit Hardouin] /*correction of a bug to save the scores*/
* Release 1.7 : August 29, 2019 [Jean-Benoit Hardouin] /*improvement of radar*/
* Release 1.8 : December 13, 2023 [Jean-Benoit Hardouin] /*Correction for individuals with exactly 50% of missing data in a scale: they should be imputed (Ware, SF36 manual) but were not imputed before*/
*
* Jean-benoit Hardouin, phD, Assistant Professor
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program :http://www.anaqol.org
*
* Copyright 2013, 2018, 2019, 2023 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 sf36fr , rclass
version 8.2
syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string) RADar FILESave DIRSave(string)]
*preserve
local nbitems : word count `varlist'
if `nbitems'!=36 {
di in red "There is `nbitems' items defined instead of 36"
}
tokenize `varlist'
local varlistsav `varlist'
local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5
local sf2
local varlist2
forvalues i=1/36 {
local j:word `i' of `sf'
tempname `j'
*di " qui gen `j'=``i''"
qui gen ``j''=``i''
local varlist2 "`varlist2' ``j''"
}
local varlist "`varlist2'"
tokenize `varlist'
*di "`varlist'"
if "`v2'"=="" {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5
}
else {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
}
forvalues i=1/36 {
local mod`i':word `i' of `modamax'
}
local error=0
local inf
local sup
local c=1
foreach i of varlist `varlist' {
qui count if `i'<1
if `r(N)'>0 {
local error=1
local inf "`inf' `i'"
}
local tmp: word `c' of `modamax'
qui count if `i'>`c'
if `r(N)'>0 {
local error=1
local inf "`sup' `i'"
}
local ++c
}
forvalues i=1/15 {
tempname inc`i'
}
local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21
local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22
*tab `11' `3'
qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=.
* tab `inc`i''
qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=.
qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=.
qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=.
qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=.
qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=.
qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=.
qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=.
qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=.
qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=.
qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=.
qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=.
qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=.
qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=.
qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=.
tempname scoreinc
genscore `inc1'-`inc15',score(`scoreinc')
if "`details'" !="" {
di "{hline 80}"
di in gr "Discrepancies" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals"
di "{hline 80}"
*di "varlist:`varlistsav'"
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
local ni1:word `i1' of `varlistsav'
local ni2:word `i2' of `varlistsav'
qui count if `inc`i''==1
di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)'
}
di "{hline 80}"
}
*list subjid `scoreinc' `inc1'-`inc15' `scoreinc' if `scoreinc'!=0&`scoreinc'!=.
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
qui replace ``i1''=. if `inc`i''==1
qui replace ``i2''=. if `inc`i''==1
}
tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh
/*PF*/
imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(5) noround prefix(`imp')
genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf')
qui replace `scorepf'=(`scorepf'-10)/20*100
/*RP*/
imputeitems `13' `14' `15' `16',max(2) noround prefix(`imp')
genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp')
qui replace `scorerp'=(`scorerp'-4)/4*100
/*BP*/
tempvar jb
qui gen `jb'=.
qui replace `jb'=6 if `21'==1&`22'==1
qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1
qui replace `jb'=4 if `22'==2&`21'!=.
qui replace `jb'=3 if `22'==3&`21'!=.
qui replace `jb'=2 if `22'==4&`21'!=.
qui replace `jb'=1 if `22'==5&`21'!=.
qui replace `jb'=6 if `22'==1&`21'==.
qui replace `jb'=4.75 if `22'==2&`21'==.
qui replace `jb'=3.5 if `22'==3&`21'==.
qui replace `jb'=2.25 if `22'==4&`21'==.
qui replace `jb'=1 if `22'==5&`21'==.
qui replace `22'=`jb'
if "`v2'"=="" {
qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1
}
else {
qui recode `21' 1=6 2=4.8 3=2.65 4=1
}
imputeitems `21' `22',max(1) noround prefix(`imp')
* replace `imp'`21'=`21'
* replace `imp'`22'=`22'
qui genscore `imp'`21' `imp'`22',score(`scorebp')
* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp'
qui replace `scorebp'=(`scorebp'-2)/10*100
*tab `scorebp'
/*GH*/
qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1
qui recode `34' 1=5 2=4 3=3 4=2 5=1
qui recode `36' 1=5 2=4 3=3 4=2 5=1
imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp')
genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh')
qui replace `scoregh'=(`scoregh'-5)/20*100
/*VT*/
if "`v2'"=="" {
qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `23' `27' `29' `31',max(2) noround prefix(`imp')
genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt')
qui replace `scorevt'=(`scorevt'-4)/20*100
/*SF*/
if "`v2'"=="" {
qui recode `20' 1=5 2=4 3=3 4=2 5=1
}
else {
qui recode `20' 1=5 2=4 3=2.5 4=1
}
imputeitems `20' `32',max(1) noround prefix(`imp')
genscore `imp'`20' `imp'`32',score(`scoresf')
qui replace `scoresf'=(`scoresf'-2)/8*100
/*RE*/
imputeitems `17' `18' `19',max(1) noround prefix(`imp')
genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere')
qui replace `scorere'=(`scorere'-3)/3*100
/*MH*/
if "`v2'"=="" {
qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp')
genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh')
qui replace `scoremh'=(`scoremh'-5)/25*100
tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs
/*scores composites*/
qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490
qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729
qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879
qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964
qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942
qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649
qui gen `scorerez'=(`scorere'-81.29467)/33.02717
qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189
qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50
qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50
/*scores composites SF12*/
tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c
tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c
qui gen `sf12p_1'=`1'
qui gen `sf12p_2a'=`4'
qui gen `sf12p_2b'=`6'
qui gen `sf12p_3a'=`14'
qui gen `sf12p_3b'=`15'
qui gen `sf12p_4a'=`18'
qui gen `sf12p_4b'=`19'
qui gen `sf12p_5'=`20'
qui gen `sf12p_6'=`32'
qui gen `sf12p_7a'=`26'
qui gen `sf12p_7b'=`27'
qui gen `sf12p_7c'=`28'
qui gen `sf12m_1'=`1'
qui gen `sf12m_2a'=`4'
qui gen `sf12m_2b'=`6'
qui gen `sf12m_3a'=`14'
qui gen `sf12m_3b'=`15'
qui gen `sf12m_4a'=`18'
qui gen `sf12m_4b'=`19'
qui gen `sf12m_5'=`20'
qui gen `sf12m_6'=`32'
qui gen `sf12m_7a'=`26'
qui gen `sf12m_7b'=`27'
qui gen `sf12m_7c'=`28'
qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399
qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175
qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0
qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0
qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0
qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0
qui recode `sf12p_3a' 1=-4.61617 2=0
qui recode `sf12m_3a' 1=1.44060 2=0
qui recode `sf12p_3b' 1=-5.51747 2=0
qui recode `sf12m_3b' 1=1.66968 2=0
qui recode `sf12p_4a' 1=3.04365 2=0
qui recode `sf12m_4a' 1=-6.82672 2=0
qui recode `sf12p_4b' 1=2.32091 2=0
qui recode `sf12m_4b' 1=-5.69921 2=0
qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0
qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0
if "`v2'"=="" {
qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619
qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0
}
else {
qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619
qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0
}
qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706
qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781
if "`save'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `save'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0 {
qui replace `save'`i'=`score`i''
}
else {
qui gen `save'`i'=`score`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv
matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24)
matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63)
matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29)
matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96)
matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03)
matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98)
matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04)
matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99)
tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh
tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv
if "`age'"!=""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75
qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75
qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75
qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75
local ++c
}
}
else if "`age'"!=""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75
qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75
local ++c
}
}
else if "`age'"==""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1
qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0
qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1
qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0
local ++c
}
}
else if "`age'"==""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
gen `scoreref`i''=`scoreref'[1,`c']
gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2
local ++c
}
}
tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs
tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv
qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490
qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729
qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879
qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964
qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942
qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649
qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717
qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189
qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50
qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50
qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2
qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2
qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2
qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2
qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2
qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2
qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2
qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2
qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2
qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2
if "`saveref'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `saveref'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0 {
qui replace `saveref'`i'=`scoreref`i''
}
else {
qui gen `saveref'`i'=`scoreref`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
if "`details'"!=""|"`radar'"!="" {
tempname radar
qui matrix `radar'=J(12,2,.)
if "`details'"!="" {
di "{hline 80}"
di in gr _col(12) "Sample" _col(51) "Reference"
di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p"
di "{hline 80}"
}
local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m
local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
qui su `score`i''
local means`i'=r(mean)
local sds`i'=r(sd)
local mins`i'=r(min)
local maxs`i'=r(max)
local n`i'=r(N)
matrix `radar'[`c',1]=`means`i''
qui su `scoreref`i''
matrix `radar'[`c',2]=r(mean)
if "`i'"!="sf12p"&"`i'"!="sf12m" {
qui su `scoreref`i'' if `score`i''!=.
local meanr`i'=r(mean)
local sdr`i'=r(sd)
local vr`i'=(`sdr`i'')^2
qui su `scoreref`i'v' if `score`i''!=.
local meanvr`i'=r(mean)
local sdr`i'=sqrt(`vr`i''+`meanvr`i'')
*local minr`i'=r(min)
*local maxr`i'=r(max)
qui ttest `score`i''=`meanr`i''
local p`i'=r(p)
}
if "`details'"!="" {
di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i''
}
local ++c
}
if "`details'"!="" {
di "{hline 80}"
}
*corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m'
*scatter `scorepcs' `scoresf12p' ,name(p)
*scatter `scoremcs' `scoresf12m' ,name(m)
*su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c'
*su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c'
if "`radar'"!=""&"`v2'"=="" {
qui tempfile radarfile
qui save `radarfile', replace
qui drop _all
qui svmat `radar'
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local c=1
qui gen name=""
foreach i in `listmin' {
qui replace name="`i'" in `c'
local ++c
}
qui rename `radar'1 scoreSF36
rename `radar'2 scoreSF36ref
qui keep in 1/10
label variable scoreSF36 "Sample"
label variable scoreSF36ref "General French population"
if "`filesave'"!="" {
if "`dirsave'"=="" {
local dirsave `c(pwd)'
}
local saving "saving(`dirsave'//radar, replace) "
}
qui radar name scoreSF36 scoreSF36ref, note("") title("Comparison of the sample with the general French population") legend(lab(1 "Sample") lab(2 "General French population")) `saving' r(0 20 40 60 80 100)
qui use `radarfile', clear
}
}
if "`saveimp'"!="" {
*su
foreach i of numlist 1 3/36 {
local j:word `i' of `varlistsav'
*di "gen `saveimp'`j'=`imp'``i''"
capture confirm variable `saveimp'`j'
if _rc==0&"`replace'"=="" {
di in ye "The variable `saveimp'`j' already exists and cannot be replaced."
}
else if _rc==0&"`replace'"!="" {
qui replace `saveimp'`j'=`imp'``i''
}
else {
qui gen `saveimp'`j'=`imp'``i''
}
}
}
*restore, preserve
end

View File

@ -0,0 +1,60 @@
{smcl}
{* 5May2013}{...}
{hline}
help for {hi:sf36fr}{right:Jean-Benoit Hardouin}
{hline}
{title:Computation of the score of the French SF36 questionnaire}
{p 8 14 2}{cmd:sf36fr} {it:varlist} [{it:if}] [,{cmdab:v2} {cmd:save}({it:prefix}) {cmd:saveref}({it:prefix}) {cmd:saveimp}({it:prefix}) {cmdab:rep:lace} {cmd:age}({it:varname}) {cmdab:sex}({it:varname}) {cmdab:det:ails}]
{title:Description}
{p 4 4 2}{cmd:sf36fr} computes the scores of the French versions of the SF36 questionnaire based on the algorithm of the version 1.3. By default, version 1.3 of the questionnaire is assumed.
For data provided using the version 2 of the SF36 questionnaire, this algorithm is adapted.
{title:Options}
{p 4 8 2}{it:varlist} must contain the name of the 36 variables representing the 36 items of the questionnaire in the same order than in the questionnaire.
{p 4 8 2}{cmd:v2} is required if the version 2 of the SF36 questionnaire is used.
{p 4 8 2}{cmd:save}({it:prefix}) saves the scores in new variables. The names of this variable are {it:prefix} followed by the names of the dimensions (PF RP BP GH VT SF RE MH PCS MCS).
{p 4 8 2}{cmd:saveref}({it:prefix}) saves the scores of reference in new variables. The names of this variable are {it:prefix} followed by the names of the dimensions (PF RP BP GH VT SF RE MH PCS MCS).
{p 4 8 2}{cmd:saveimp}({it:prefix}) saves the imputed values of each items in variables using the string as prefix followed the name of each items.
{p 4 8 2}{cmdab:rep:lace} allows replacing the variables defined with the {cmd:save} and {cmd:saveref} options if required.
{p 4 8 2}{cmd:age}({it:varname}) and {cmd:sex}({it:varname}) define the age and sex of the individuals in order to compute more precisely the scores of reference.
{p 4 8 2}{cmdab:det:ails} displays tables of incoherencs and comparison between computed scores and scores of reference.
{title:Example}
{cmd:. sf36fr sf36_1 - sf36_11d}
{cmd:. sf36fr sf36_1 - sf36_11d, v2 save(score) details replace}
{cmd:. sf36fr sf36_1 - sf36_11d, v2 save(score) details saveref(scoreref) age(age) sex(sexe)}
{title:Reference}
{p 4 8 2}{cmd:Lepl<70>ge A, Ecosse E, Pouchot J, Coste J, Perneger T} (2001). Le questionnaire MOS-SF36 - Manuel de l'utilisateur et guide d'interpr<70>tation des scores. Estem: Paris.
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
{p 4 8 2}EA 4275 "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}Website {browse "http://www.anaqol.org":AnaQol}

Binary file not shown.

View File

@ -0,0 +1,550 @@
*! Version 1.4 1 December 2018
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : sf36fr
* computes score of the French SF36 questionnnaire
* Release 1 : May 2, 2013 [Jean-benoit Hardouin]
* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/
* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/
*
*
* Historic :
* Version 1 (May 2, 2013) [Jean-Benoit Hardouin]
*
* Faire sauvegarde des items imput<75>s
*
* 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 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 sf36fr , rclass
version 8.2
syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string)]
local nbitems : word count `varlist'
if `nbitems'!=36 {
di in red "There is `nbitems' items defined instead of 36"
}
tokenize `varlist'
local varlistsav `varlist'
local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5
local sf2
local varlist2
forvalues i=1/36 {
local j:word `i' of `sf'
tempname `j'
*di " qui gen `j'=``i''"
qui gen ``j''=``i''
local varlist2 "`varlist2' ``j''"
}
local varlist "`varlist2'"
tokenize `varlist'
*di "`varlist'"
if "`v2'"=="" {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5
}
else {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
}
forvalues i=1/36 {
local mod`i':word `i' of `modamax'
}
local error=0
local inf
local sup
local c=1
foreach i of varlist `varlist' {
qui count if `i'<1
if `r(N)'>0 {
local error=1
local inf "`inf' `i'"
}
local tmp: word `c' of `modamax'
qui count if `i'>`c'
if `r(N)'>0 {
local error=1
local inf "`sup' `i'"
}
local ++c
}
forvalues i=1/15 {
tempname inc`i'
}
local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21
local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22
*tab `11' `3'
qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=.
* tab `inc`i''
qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=.
qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=.
qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=.
qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=.
qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=.
qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=.
qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=.
qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=.
qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=.
qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=.
qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=.
qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=.
qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=.
qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=.
tempname scoreinc
genscore `inc1'-`inc15',score(`scoreinc')
if "`details'" !="" {
di "{hline 80}"
di in gr "Incoherences" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals"
di "{hline 80}"
*di "varlist:`varlistsav'"
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
local ni1:word `i1' of `varlistsav'
local ni2:word `i2' of `varlistsav'
qui count if `inc`i''==1
di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)'
}
di "{hline 80}"
}
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
qui replace ``i1''=. if `inc`i''==1
qui replace ``i2''=. if `inc`i''==1
}
tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh
/*PF*/
imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp')
genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf')
qui replace `scorepf'=(`scorepf'-10)/20*100
/*RP*/
imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp')
genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp')
qui replace `scorerp'=(`scorerp'-4)/4*100
/*BP*/
tempvar jb
qui gen `jb'=.
qui replace `jb'=6 if `21'==1&`22'==1
qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1
qui replace `jb'=4 if `22'==2&`21'!=.
qui replace `jb'=3 if `22'==3&`21'!=.
qui replace `jb'=2 if `22'==4&`21'!=.
qui replace `jb'=1 if `22'==5&`21'!=.
qui replace `jb'=6 if `22'==1&`21'==.
qui replace `jb'=4.75 if `22'==2&`21'==.
qui replace `jb'=3.5 if `22'==3&`21'==.
qui replace `jb'=2.25 if `22'==4&`21'==.
qui replace `jb'=1 if `22'==5&`21'==.
qui replace `22'=`jb'
if "`v2'"=="" {
qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1
}
else {
qui recode `21' 1=6 2=4.8 3=2.65 4=1
}
imputeitems `21' `22',max(0) noround prefix(`imp')
* replace `imp'`21'=`21'
* replace `imp'`22'=`22'
qui genscore `imp'`21' `imp'`22',score(`scorebp')
* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp'
qui replace `scorebp'=(`scorebp'-2)/10*100
*tab `scorebp'
/*GH*/
qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1
qui recode `34' 1=5 2=4 3=3 4=2 5=1
qui recode `36' 1=5 2=4 3=3 4=2 5=1
imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp')
genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh')
qui replace `scoregh'=(`scoregh'-5)/20*100
/*VT*/
if "`v2'"=="" {
qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp')
genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt')
qui replace `scorevt'=(`scorevt'-4)/20*100
/*SF*/
if "`v2'"=="" {
qui recode `20' 1=5 2=4 3=3 4=2 5=1
}
else {
qui recode `20' 1=5 2=4 3=2.5 4=1
}
imputeitems `20' `32',max(0) noround prefix(`imp')
genscore `imp'`20' `imp'`32',score(`scoresf')
qui replace `scoresf'=(`scoresf'-2)/8*100
/*RE*/
imputeitems `17' `18' `19',max(1) noround prefix(`imp')
genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere')
qui replace `scorere'=(`scorere'-3)/3*100
/*MH*/
if "`v2'"=="" {
qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp')
genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh')
qui replace `scoremh'=(`scoremh'-5)/25*100
tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs
/*scores composites*/
qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490
qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729
qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879
qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964
qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942
qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649
qui gen `scorerez'=(`scorere'-81.29467)/33.02717
qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189
qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50
qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50
/*scores composites SF12*/
tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c
tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c
qui gen `sf12p_1'=`1'
qui gen `sf12p_2a'=`4'
qui gen `sf12p_2b'=`6'
qui gen `sf12p_3a'=`14'
qui gen `sf12p_3b'=`15'
qui gen `sf12p_4a'=`18'
qui gen `sf12p_4b'=`19'
qui gen `sf12p_5'=`20'
qui gen `sf12p_6'=`32'
qui gen `sf12p_7a'=`26'
qui gen `sf12p_7b'=`27'
qui gen `sf12p_7c'=`28'
qui gen `sf12m_1'=`1'
qui gen `sf12m_2a'=`4'
qui gen `sf12m_2b'=`6'
qui gen `sf12m_3a'=`14'
qui gen `sf12m_3b'=`15'
qui gen `sf12m_4a'=`18'
qui gen `sf12m_4b'=`19'
qui gen `sf12m_5'=`20'
qui gen `sf12m_6'=`32'
qui gen `sf12m_7a'=`26'
qui gen `sf12m_7b'=`27'
qui gen `sf12m_7c'=`28'
qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399
qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175
qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0
qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0
qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0
qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0
qui recode `sf12p_3a' 1=-4.61617 2=0
qui recode `sf12m_3a' 1=1.44060 2=0
qui recode `sf12p_3b' 1=-5.51747 2=0
qui recode `sf12m_3b' 1=1.66968 2=0
qui recode `sf12p_4a' 1=3.04365 2=0
qui recode `sf12m_4a' 1=-6.82672 2=0
qui recode `sf12p_4b' 1=2.32091 2=0
qui recode `sf12m_4b' 1=-5.69921 2=0
qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0
qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0
if "`v2'"=="" {
qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619
qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0
}
else {
qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619
qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0
}
qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706
qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781
if "`save'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `save'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0 {
qui replace `save'`i'=`score`i''
}
else {
qui gen `save'`i'=`score`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv
matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24)
matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63)
matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29)
matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96)
matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03)
matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98)
matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04)
matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99)
tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh
tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv
if "`age'"!=""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75
qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75
qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75
qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75
local ++c
}
}
else if "`age'"!=""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75
qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75
local ++c
}
}
else if "`age'"==""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1
qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0
qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1
qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0
local ++c
}
}
else if "`age'"==""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
gen `scoreref`i''=`scoreref'[1,`c']
gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2
local ++c
}
}
tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs
tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv
qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490
qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729
qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879
qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964
qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942
qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649
qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717
qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189
qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50
qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50
qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2
qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2
qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2
qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2
qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2
qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2
qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2
qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2
qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2
qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2
if "`saveref'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `saveref'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0 {
qui replace `saveref'`i'=`scoreref`i''
}
else {
qui gen `saveref'`i'=`scoreref`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
if "`details'"!="" {
di "{hline 80}"
di in gr _col(12) "Sample" _col(51) "Reference"
di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p"
di "{hline 80}"
local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m
local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
qui su `score`i''
local means`i'=r(mean)
local sds`i'=r(sd)
local mins`i'=r(min)
local maxs`i'=r(max)
local n`i'=r(N)
if "`i'"!="sf12p"&"`i'"!="sf12m" {
qui su `scoreref`i'' if `score`i''!=.
local meanr`i'=r(mean)
local sdr`i'=r(sd)
local vr`i'=(`sdr`i'')^2
qui su `scoreref`i'v' if `score`i''!=.
local meanvr`i'=r(mean)
local sdr`i'=sqrt(`vr`i''+`meanvr`i'')
*local minr`i'=r(min)
*local maxr`i'=r(max)
qui ttest `score`i''=`meanr`i''
local p`i'=r(p)
}
di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i''
local ++c
}
di "{hline 80}"
*corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m'
*scatter `scorepcs' `scoresf12p' ,name(p)
*scatter `scoremcs' `scoresf12m' ,name(m)
*su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c'
*su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c'
}
if "`saveimp'"!="" {
*su
foreach i of numlist 1 3/36 {
local j:word `i' of `varlistsav'
*di "gen `saveimp'`j'=`imp'``i''"
capture confirm variable `saveimp'`j'
if _rc==0&"`replace'"=="" {
di in ye "The variable `saveimp'`j' already exists and cannot be replaced."
}
else if _rc==0&"`replace'"!="" {
qui replace `saveimp'`j'=`imp'``i''
}
else {
qui gen `saveimp'`j'=`imp'``i''
}
}
}
end

View File

@ -0,0 +1,585 @@
*! Version 1.5 29July2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : sf36fr
* computes score of the French SF36 questionnnaire
*
*
* Historic :
* Version 1 (May 2, 2013) [Jean-Benoit Hardouin]
* Release 1 : May 2, 2013 [Jean-benoit Hardouin]
* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/
* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.4 : December 1, 2018 [Jean-Benoit Hardouin] /*correction of a bug on SF12*/
* Release 1.5 : July 29, 2019 [Jean-Benoit Hardouin] /*radar option*/
*
* Jean-benoit Hardouin, phD, Assistant Professor
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* jean-benoit.hardouin@univ-nantes.fr
*
* News about this program :http://www.anaqol.org
*
* Copyright 2013, 2018, 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
*
***********************************************************************************************************
program define sf36fr , rclass
version 8.2
syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string) RADar FILESave DIRSave(string)]
preserve
local nbitems : word count `varlist'
if `nbitems'!=36 {
di in red "There is `nbitems' items defined instead of 36"
}
tokenize `varlist'
local varlistsav `varlist'
local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5
local sf2
local varlist2
forvalues i=1/36 {
local j:word `i' of `sf'
tempname `j'
*di " qui gen `j'=``i''"
qui gen ``j''=``i''
local varlist2 "`varlist2' ``j''"
}
local varlist "`varlist2'"
tokenize `varlist'
*di "`varlist'"
if "`v2'"=="" {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5
}
else {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
}
forvalues i=1/36 {
local mod`i':word `i' of `modamax'
}
local error=0
local inf
local sup
local c=1
foreach i of varlist `varlist' {
qui count if `i'<1
if `r(N)'>0 {
local error=1
local inf "`inf' `i'"
}
local tmp: word `c' of `modamax'
qui count if `i'>`c'
if `r(N)'>0 {
local error=1
local inf "`sup' `i'"
}
local ++c
}
forvalues i=1/15 {
tempname inc`i'
}
local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21
local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22
*tab `11' `3'
qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=.
* tab `inc`i''
qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=.
qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=.
qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=.
qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=.
qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=.
qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=.
qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=.
qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=.
qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=.
qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=.
qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=.
qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=.
qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=.
qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=.
tempname scoreinc
genscore `inc1'-`inc15',score(`scoreinc')
if "`details'" !="" {
di "{hline 80}"
di in gr "Incoherences" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals"
di "{hline 80}"
*di "varlist:`varlistsav'"
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
local ni1:word `i1' of `varlistsav'
local ni2:word `i2' of `varlistsav'
qui count if `inc`i''==1
di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)'
}
di "{hline 80}"
}
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
qui replace ``i1''=. if `inc`i''==1
qui replace ``i2''=. if `inc`i''==1
}
tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh
/*PF*/
imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp')
genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf')
qui replace `scorepf'=(`scorepf'-10)/20*100
/*RP*/
imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp')
genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp')
qui replace `scorerp'=(`scorerp'-4)/4*100
/*BP*/
tempvar jb
qui gen `jb'=.
qui replace `jb'=6 if `21'==1&`22'==1
qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1
qui replace `jb'=4 if `22'==2&`21'!=.
qui replace `jb'=3 if `22'==3&`21'!=.
qui replace `jb'=2 if `22'==4&`21'!=.
qui replace `jb'=1 if `22'==5&`21'!=.
qui replace `jb'=6 if `22'==1&`21'==.
qui replace `jb'=4.75 if `22'==2&`21'==.
qui replace `jb'=3.5 if `22'==3&`21'==.
qui replace `jb'=2.25 if `22'==4&`21'==.
qui replace `jb'=1 if `22'==5&`21'==.
qui replace `22'=`jb'
if "`v2'"=="" {
qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1
}
else {
qui recode `21' 1=6 2=4.8 3=2.65 4=1
}
imputeitems `21' `22',max(0) noround prefix(`imp')
* replace `imp'`21'=`21'
* replace `imp'`22'=`22'
qui genscore `imp'`21' `imp'`22',score(`scorebp')
* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp'
qui replace `scorebp'=(`scorebp'-2)/10*100
*tab `scorebp'
/*GH*/
qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1
qui recode `34' 1=5 2=4 3=3 4=2 5=1
qui recode `36' 1=5 2=4 3=3 4=2 5=1
imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp')
genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh')
qui replace `scoregh'=(`scoregh'-5)/20*100
/*VT*/
if "`v2'"=="" {
qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp')
genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt')
qui replace `scorevt'=(`scorevt'-4)/20*100
/*SF*/
if "`v2'"=="" {
qui recode `20' 1=5 2=4 3=3 4=2 5=1
}
else {
qui recode `20' 1=5 2=4 3=2.5 4=1
}
imputeitems `20' `32',max(0) noround prefix(`imp')
genscore `imp'`20' `imp'`32',score(`scoresf')
qui replace `scoresf'=(`scoresf'-2)/8*100
/*RE*/
imputeitems `17' `18' `19',max(1) noround prefix(`imp')
genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere')
qui replace `scorere'=(`scorere'-3)/3*100
/*MH*/
if "`v2'"=="" {
qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp')
genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh')
qui replace `scoremh'=(`scoremh'-5)/25*100
tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs
/*scores composites*/
qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490
qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729
qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879
qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964
qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942
qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649
qui gen `scorerez'=(`scorere'-81.29467)/33.02717
qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189
qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50
qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50
/*scores composites SF12*/
tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c
tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c
qui gen `sf12p_1'=`1'
qui gen `sf12p_2a'=`4'
qui gen `sf12p_2b'=`6'
qui gen `sf12p_3a'=`14'
qui gen `sf12p_3b'=`15'
qui gen `sf12p_4a'=`18'
qui gen `sf12p_4b'=`19'
qui gen `sf12p_5'=`20'
qui gen `sf12p_6'=`32'
qui gen `sf12p_7a'=`26'
qui gen `sf12p_7b'=`27'
qui gen `sf12p_7c'=`28'
qui gen `sf12m_1'=`1'
qui gen `sf12m_2a'=`4'
qui gen `sf12m_2b'=`6'
qui gen `sf12m_3a'=`14'
qui gen `sf12m_3b'=`15'
qui gen `sf12m_4a'=`18'
qui gen `sf12m_4b'=`19'
qui gen `sf12m_5'=`20'
qui gen `sf12m_6'=`32'
qui gen `sf12m_7a'=`26'
qui gen `sf12m_7b'=`27'
qui gen `sf12m_7c'=`28'
qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399
qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175
qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0
qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0
qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0
qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0
qui recode `sf12p_3a' 1=-4.61617 2=0
qui recode `sf12m_3a' 1=1.44060 2=0
qui recode `sf12p_3b' 1=-5.51747 2=0
qui recode `sf12m_3b' 1=1.66968 2=0
qui recode `sf12p_4a' 1=3.04365 2=0
qui recode `sf12m_4a' 1=-6.82672 2=0
qui recode `sf12p_4b' 1=2.32091 2=0
qui recode `sf12m_4b' 1=-5.69921 2=0
qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=0.11038 5=0
qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0
if "`v2'"=="" {
qui recode `sf12p_5' 5=0 4=-3.80130 3=-6.50522 2=-8.38063 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619
qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0
}
else {
qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619
qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0
}
qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706
qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781
if "`save'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `save'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0 {
qui replace `save'`i'=`score`i''
}
else {
qui gen `save'`i'=`score`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv
matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24)
matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63)
matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29)
matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96)
matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03)
matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98)
matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04)
matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99)
tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh
tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv
if "`age'"!=""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75
qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75
qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75
qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75
local ++c
}
}
else if "`age'"!=""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75
qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75
local ++c
}
}
else if "`age'"==""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1
qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0
qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1
qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0
local ++c
}
}
else if "`age'"==""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
gen `scoreref`i''=`scoreref'[1,`c']
gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2
local ++c
}
}
tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs
tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv
qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490
qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729
qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879
qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964
qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942
qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649
qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717
qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189
qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50
qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50
qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2
qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2
qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2
qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2
qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2
qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2
qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2
qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2
qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2
qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2
if "`saveref'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `saveref'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0 {
qui replace `saveref'`i'=`scoreref`i''
}
else {
qui gen `saveref'`i'=`scoreref`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
if "`details'"!=""|"`radar'"!="" {
tempname radar
qui matrix `radar'=J(12,2,.)
if "`details'"!="" {
di "{hline 80}"
di in gr _col(12) "Sample" _col(51) "Reference"
di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p"
di "{hline 80}"
}
local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m
local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
qui su `score`i''
local means`i'=r(mean)
local sds`i'=r(sd)
local mins`i'=r(min)
local maxs`i'=r(max)
local n`i'=r(N)
matrix `radar'[`c',1]=`means`i''
qui su `scoreref`i''
matrix `radar'[`c',2]=r(mean)
if "`i'"!="sf12p"&"`i'"!="sf12m" {
qui su `scoreref`i'' if `score`i''!=.
local meanr`i'=r(mean)
local sdr`i'=r(sd)
local vr`i'=(`sdr`i'')^2
qui su `scoreref`i'v' if `score`i''!=.
local meanvr`i'=r(mean)
local sdr`i'=sqrt(`vr`i''+`meanvr`i'')
*local minr`i'=r(min)
*local maxr`i'=r(max)
qui ttest `score`i''=`meanr`i''
local p`i'=r(p)
}
if "`details'"!="" {
di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i''
}
local ++c
}
if "`details'"!="" {
di "{hline 80}"
}
*corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m'
*scatter `scorepcs' `scoresf12p' ,name(p)
*scatter `scoremcs' `scoresf12m' ,name(m)
*su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c'
*su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c'
if "`radar'"!=""&"`v2'"=="" {
qui tempfile radarfile
qui save `radarfile', replace
qui drop _all
qui svmat `radar'
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local c=1
qui gen name=""
foreach i in `listmin' {
qui replace name="`i'" in `c'
local ++c
}
qui rename `radar'1 scoreSF36
rename `radar'2 scoreSF36ref
qui keep in 1/10
label variable scoreSF36 "Sample"
label variable scoreSF36ref "General French population"
if "`filesave'"!="" {
if "`dirsave'"=="" {
local dirsave `c(pwd)'
}
local saving "saving(`dirsave'//radar, replace) "
}
qui radar name scoreSF36 scoreSF36ref, note("") title("Comparison of the sample with the general French population") legend(lab(1 "Sample") lab(2 "General French population")) `saving'
qui use `radarfile', clear
}
}
if "`saveimp'"!="" {
*su
foreach i of numlist 1 3/36 {
local j:word `i' of `varlistsav'
*di "gen `saveimp'`j'=`imp'``i''"
capture confirm variable `saveimp'`j'
if _rc==0&"`replace'"=="" {
di in ye "The variable `saveimp'`j' already exists and cannot be replaced."
}
else if _rc==0&"`replace'"!="" {
qui replace `saveimp'`j'=`imp'``i''
}
else {
qui gen `saveimp'`j'=`imp'``i''
}
}
}
restore, preserve
end

View File

@ -0,0 +1,549 @@
*! Version 1.3 24 May 2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : sf36fr
* computes score of the French SF36 questionnnaire
* Release 1 : May 2, 2013 [Jean-benoit Hardouin]
* Release 1.1 : May 14, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
* Release 1.2 : May 21, 2013 [Jean-Benoit Hardouin] /*saveimp option*/
* Release 1.3 : May 24, 2013 [Jean-Benoit Hardouin] /*correction of a bug on BP*/
*
*
* Historic :
* Version 1 (May 2, 2013) [Jean-Benoit Hardouin]
*
* Faire sauvegarde des items imput<75>s
*
* 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 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 sf36fr , rclass
version 8.2
syntax varlist(min=36 max=36 numeric) [,v2 save(string) REPlace age(varname) SEXe(varname) saveref(string) DETails saveimp(string)]
local nbitems : word count `varlist'
if `nbitems'!=36 {
di in red "There is `nbitems' items defined instead of 36"
}
tokenize `varlist'
local varlistsav `varlist'
local sf gh1 ht pf1 pf2 pf3 pf4 pf5 pf6 pf7 pf8 pf9 pf10 rp1 rp2 rp3 rp4 re1 re2 re3 sf1 bp1 bp2 vt1 mh1 mh2 mh3 vt2 mh4 vt3 mh5 vt4 sf2 gh2 gh3 gh4 gh5
local sf2
local varlist2
forvalues i=1/36 {
local j:word `i' of `sf'
tempname `j'
*di " qui gen `j'=``i''"
qui gen ``j''=``i''
local varlist2 "`varlist2' ``j''"
}
local varlist "`varlist2'"
tokenize `varlist'
*di "`varlist'"
if "`v2'"=="" {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 5 6 5 6 6 6 6 6 6 6 6 6 5 5 5 5 5
}
else {
local modamax 5 5 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
}
forvalues i=1/36 {
local mod`i':word `i' of `modamax'
}
local error=0
local inf
local sup
local c=1
foreach i of varlist `varlist' {
qui count if `i'<1
if `r(N)'>0 {
local error=1
local inf "`inf' `i'"
}
local tmp: word `c' of `modamax'
qui count if `i'>`c'
if `r(N)'>0 {
local error=1
local inf "`sup' `i'"
}
local ++c
}
forvalues i=1/15 {
tempname inc`i'
}
local liste1 11 12 11 12 11 12 11 12 30 24 27 23 1 20 21
local liste2 3 3 4 4 6 6 9 9 25 26 29 31 36 32 22
*tab `11' `3'
qui gen `inc1'=`11'==1&`3'>1 if `11'!=.&`3'!=.
* tab `inc`i''
qui gen `inc2'=`12'==1&`3'>1 if `12'!=.&`3'!=.
qui gen `inc3'=`11'==1&`4'>1 if `11'!=.&`4'!=.
qui gen `inc4'=`12'==1&`4'>1 if `12'!=.&`4'!=.
qui gen `inc5'=`11'==1&`6'>1 if `11'!=.&`6'!=.
qui gen `inc6'=`12'==1&`6'>1 if `12'!=.&`6'!=.
qui gen `inc7'=`11'==1&`9'>1 if `11'!=.&`9'!=.
qui gen `inc8'=`12'==1&`9'>1 if `12'!=.&`9'!=.
qui gen `inc9'=(`30'==1&`25'==1)|(`30'==`mod30'&`25'==`mod25') if `30'!=.&`25'!=.
qui gen `inc10'=(`24'==1&`26'==1)|(`24'==`mod24'&`26'==`mod26') if `24'!=.&`26'!=.
qui gen `inc11'=(`27'==1&`29'==1)|(`27'==`mod27'&`29'==`mod29') if `27'!=.&`29'!=.
qui gen `inc12'=(`23'==1&`31'==1)|(`23'==`mod23'&`31'==`mod31') if `23'!=.&`31'!=.
qui gen `inc13'=(`1'==1&`36'==`mod36')|(`1'==`mod1'&`36'==1) if `1'!=.&`36'!=.
qui gen `inc14'=(`20'==1&`32'==1)|(`20'==`mod20'&`32'==`mod32') if `20'!=.&`32'!=.
qui gen `inc15'=(`21'==1&`22'==`mod22')|(`21'==`mod21'&`22'==1) if `21'!=.&`22'!=.
tempname scoreinc
genscore `inc1'-`inc15',score(`scoreinc')
if "`details'" !="" {
di "{hline 80}"
di in gr "Incoherences" _col(20) "item 1" _col(40) "item 2" _col(60) "# individuals"
di "{hline 80}"
*di "varlist:`varlistsav'"
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
local ni1:word `i1' of `varlistsav'
local ni2:word `i2' of `varlistsav'
qui count if `inc`i''==1
di in gr "`i'" in ye _col(20) abbrev("`ni1'",19) _col(40) abbrev("`ni2'",19) %6.0f _col(67) `r(N)'
}
di "{hline 80}"
}
forvalues i=1/15 {
local i1:word `i' of `liste1'
local i2:word `i' of `liste2'
qui replace ``i1''=. if `inc`i''==1
qui replace ``i2''=. if `inc`i''==1
}
tempname imp scorepf scorerp scorebp scoregh scorevt scoresf scorere scoremh
/*PF*/
imputeitems `3' `4' `5' `6' `7' `8' `9' `10' `11' `12',max(4) noround prefix(`imp')
genscore `imp'`3' `imp'`4' `imp'`5' `imp'`6' `imp'`7' `imp'`8' `imp'`9' `imp'`10' `imp'`11' `imp'`12',score(`scorepf')
qui replace `scorepf'=(`scorepf'-10)/20*100
/*RP*/
imputeitems `13' `14' `15' `16',max(1) noround prefix(`imp')
genscore `imp'`13' `imp'`14' `imp'`15' `imp'`16',score(`scorerp')
qui replace `scorerp'=(`scorerp'-4)/4*100
/*BP*/
tempvar jb
qui gen `jb'=.
qui replace `jb'=6 if `21'==1&`22'==1
qui replace `jb'=5 if `21'>=2&`21'<=6&`22'==1
qui replace `jb'=4 if `22'==2&`21'!=.
qui replace `jb'=3 if `22'==3&`21'!=.
qui replace `jb'=2 if `22'==4&`21'!=.
qui replace `jb'=1 if `22'==5&`21'!=.
qui replace `jb'=6 if `22'==1&`21'==.
qui replace `jb'=4.75 if `22'==2&`21'==.
qui replace `jb'=3.5 if `22'==3&`21'==.
qui replace `jb'=2.25 if `22'==4&`21'==.
qui replace `jb'=1 if `22'==5&`21'==.
qui replace `22'=`jb'
if "`v2'"=="" {
qui recode `21' 1=6 2=5.4 3=4.2 4=3.1 5=2.2 6=1
}
else {
qui recode `21' 1=6 2=4.8 3=2.65 4=1
}
imputeitems `21' `22',max(0) noround prefix(`imp')
* replace `imp'`21'=`21'
* replace `imp'`22'=`22'
qui genscore `imp'`21' `imp'`22',score(`scorebp')
* list sf36_7q_intensite_douleurs sf36_8q_douleurs_physiques `21' `22' `imp'`21' `imp'`22' `scorebp'
qui replace `scorebp'=(`scorebp'-2)/10*100
*tab `scorebp'
/*GH*/
qui recode `1' 1=5 2=4.4 3=3.4 4=2 5=1
qui recode `34' 1=5 2=4 3=3 4=2 5=1
qui recode `36' 1=5 2=4 3=3 4=2 5=1
imputeitems `1' `33' `34' `35' `36',max(2) noround prefix(`imp')
genscore `imp'`1' `imp'`33' `imp'`34' `imp'`35' `imp'`36',score(`scoregh')
qui replace `scoregh'=(`scoregh'-5)/20*100
/*VT*/
if "`v2'"=="" {
qui recode `23' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `27' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `23' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `27' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `29' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `31' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `23' `27' `29' `31',max(1) noround prefix(`imp')
genscore `imp'`23' `imp'`27' `imp'`29' `imp'`31',score(`scorevt')
qui replace `scorevt'=(`scorevt'-4)/20*100
/*SF*/
if "`v2'"=="" {
qui recode `20' 1=5 2=4 3=3 4=2 5=1
}
else {
qui recode `20' 1=5 2=4 3=2.5 4=1
}
imputeitems `20' `32',max(0) noround prefix(`imp')
genscore `imp'`20' `imp'`32',score(`scoresf')
qui replace `scoresf'=(`scoresf'-2)/8*100
/*RE*/
imputeitems `17' `18' `19',max(1) noround prefix(`imp')
genscore `imp'`17' `imp'`18' `imp'`19',score(`scorere')
qui replace `scorere'=(`scorere'-3)/3*100
/*MH*/
if "`v2'"=="" {
qui recode `26' 1=6 2=5 3=4 4=3 5=2 6=1
qui recode `30' 1=6 2=5 3=4 4=3 5=2 6=1
}
else {
qui recode `26' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `30' 1=6 2=4.5 3=3.5 4=2 5=1
qui recode `24' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `25' 1=1 2=2 3=3.5 4=4.5 5=6
qui recode `28' 1=1 2=2 3=3.5 4=4.5 5=6
}
imputeitems `24' `25' `26' `28' `30',max(2) noround prefix(`imp')
genscore `imp'`24' `imp'`25' `imp'`26' `imp'`28' `imp'`30',score(`scoremh')
qui replace `scoremh'=(`scoremh'-5)/25*100
tempname scorepfz scorerpz scorebpz scoreghz scorevtz scoresfz scorerez scoremhz scorepcs scoremcs
/*scores composites*/
qui gen `scorepfz'=(`scorepf'-84.52404)/22.89490
qui gen `scorerpz'=(`scorerp'-81.19907)/33.79729
qui gen `scorebpz'=(`scorebp'-75.49196)/23.55879
qui gen `scoreghz'=(`scoregh'-72.21316)/20.16964
qui gen `scorevtz'=(`scorevt'-61.05453)/20.86942
qui gen `scoresfz'=(`scoresf'-83.59753)/22.37649
qui gen `scorerez'=(`scorere'-81.29467)/33.02717
qui gen `scoremhz'=(`scoremh'-74.84212)/18.01189
qui gen `scorepcs'=(`scorepfz'*0.42402+`scorerpz'*0.35119+`scorebpz'*0.31754+`scoreghz'*0.24954+`scorevtz'*0.02877-`scoresfz'*0.0753-`scorerez'*0.19206-`scoremhz'*0.22069)*10+50
qui gen `scoremcs'=(-`scorepfz'*0.22999-`scorerpz'*0.12329-`scorebpz'*0.09731-`scoreghz'*0.01571+`scorevtz'*0.23534+`scoresfz'*0.26876+`scorerez'*0.43407+`scoremhz'*0.48581)*10+50
/*scores composites SF12*/
tempname scoresf12p sf12p_1 sf12p_2a sf12p_2b sf12p_3a sf12p_3b sf12p_4a sf12p_4b sf12p_5 sf12p_6 sf12p_7a sf12p_7b sf12p_7c
tempname scoresf12m sf12m_1 sf12m_2a sf12m_2b sf12m_3a sf12m_3b sf12m_4a sf12m_4b sf12m_5 sf12m_6 sf12m_7a sf12m_7b sf12m_7c
qui gen `sf12p_1'=`1'
qui gen `sf12p_2a'=`4'
qui gen `sf12p_2b'=`6'
qui gen `sf12p_3a'=`14'
qui gen `sf12p_3b'=`15'
qui gen `sf12p_4a'=`18'
qui gen `sf12p_4b'=`19'
qui gen `sf12p_5'=`20'
qui gen `sf12p_6'=`32'
qui gen `sf12p_7a'=`26'
qui gen `sf12p_7b'=`27'
qui gen `sf12p_7c'=`28'
qui gen `sf12m_1'=`1'
qui gen `sf12m_2a'=`4'
qui gen `sf12m_2b'=`6'
qui gen `sf12m_3a'=`14'
qui gen `sf12m_3b'=`15'
qui gen `sf12m_4a'=`18'
qui gen `sf12m_4b'=`19'
qui gen `sf12m_5'=`20'
qui gen `sf12m_6'=`32'
qui gen `sf12m_7a'=`26'
qui gen `sf12m_7b'=`27'
qui gen `sf12m_7c'=`28'
qui recode `sf12p_1' 5=0 4.4=-1.31872 3.4=-3.02396 2=-5.56461 1=-8.37399
qui recode `sf12m_1' 5=0 4.4=-0.06064 3.4=0.03482 2=-0.16891 1=-1.71175
qui recode `sf12p_2a' 1=-7.23216 2=-3.45555 3=0
qui recode `sf12m_2a' 1=3.93115 2=1.86840 3=0
qui recode `sf12p_2b' 1=-6.24397 2=-2.73557 3=0
qui recode `sf12m_2b' 1=2.68282 2=1.43103 3=0
qui recode `sf12p_3a' 1=-4.61617 2=0
qui recode `sf12m_3a' 1=1.44060 2=0
qui recode `sf12p_3b' 1=-5.51747 2=0
qui recode `sf12m_3b' 1=1.66968 2=0
qui recode `sf12p_4a' 1=3.04365 2=0
qui recode `sf12m_4a' 1=-6.82672 2=0
qui recode `sf12p_4b' 1=2.32091 2=0
qui recode `sf12m_4b' 1=-5.69921 2=0
qui recode `sf12p_6' 1=-0.33682 2=-0.94342 3=-0.18043 4=-0.11038 5=0
qui recode `sf12m_6' 1=-6.29724 2=-8.26066 3=-5.63286 4=-3.13896 5=0
if "`v2'"=="" {
qui recode `sf12p_5' 5=0 4=-3.83130 3=-6.50522 2=-8.38063 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 3=1.49384 2=1.76691 1=1.48619
qui recode `sf12p_7a' 6=0 5=0.66514 4=1.36689 3=2.37241 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 5=-1.94949 4=-4.09842 3=-6.31121 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 5=-0.42251 4=-1.14387 3=-1.61850 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 5=-0.92057 4=-1.65178 3=-3.29805 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3=2.34247 4=1.28044 5=0.41188 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3=-8.09914 4=-4.59055 5=-1.95934 6=0
}
else {
qui recode `sf12p_5' 5=0 4=-3.83130 2.5=-7.442925 1=-11.25544
qui recode `sf12m_5' 5=0 4=0.90384 2.5=1.630375 1=1.48619
qui recode `sf12p_7a' 6=0 4.5=1.016015 3.5=1.86965 2=2.90426 1=3.46638
qui recode `sf12m_7a' 6=0 4.5=-3.023955 3.5=-5.204815 2=-7.92717 1=-10.19085
qui recode `sf12p_7b' 6=0 4.5=-0.78319 3.5=-1.381185 2=-2.02168 1=-2.44706
qui recode `sf12m_7b' 6=0 4.5=-1.286175 3.5=-2.474915 2=-4.88962 1=-6.02409
qui recode `sf12p_7c' 1=4.61446 2=3.41593 3.5=1.811455 4.5=0.84616 6=0
qui recode `sf12m_7c' 1=-16.15395 2=-10.77911 3.5=-6.344845 4.5=-3.274945 6=0
}
qui gen `scoresf12p'=`sf12p_1'+`sf12p_2a'+`sf12p_2b'+`sf12p_3a'+`sf12p_3b'+`sf12p_4a'+`sf12p_4b'+`sf12p_5'+`sf12p_6'+`sf12p_7a'+`sf12p_7b'+`sf12p_7c'+56.57706
qui gen `scoresf12m'=`sf12m_1'+`sf12m_2a'+`sf12m_2b'+`sf12m_3a'+`sf12m_3b'+`sf12m_4a'+`sf12m_4b'+`sf12m_5'+`sf12m_6'+`sf12m_7a'+`sf12m_7b'+`sf12m_7c'+60.75781
if "`save'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `save'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `save'`i'
if _rc==0 {
qui replace `save'`i'=`score`i''
}
else {
qui gen `save'`i'=`score`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
tempname scoreref1 scoreref0 scoreref01 scoreref scorerefv1 scorerefv0 scorerefv01 scorerefv
matrix `scoreref1'=(96.65,95.80,86.82,82.36,67.86,89.76,93.14,72.85\95.75,91.16,83.60,76.07,64.50,86.50,90.64,72.08\94.41,90.76,81.03,73.13,64.32,86.37,89.07,71.01\92.27,88.64,79.02,72.27,66.06,86.69,90.00,71.53\82.32,79.81,70.21,65.97,60.19,83.33,83.00,71.10\76.58,74.74,67.10,62.37,58.21,79.74,80.04,71.16\67.16,61.28,63.99,58.61,53.93,76.16,66.67,70.24)
matrix `scoreref0'=(94.92,89.54,79.37,71.81,60.32,79.65,81.65,64.92\92.42,85.98,80.19,75.10,60.57,82.83,86.13,68.18\91.04,88.87,78.27,74.64,61.94,84.14,85.48,67.59\86.23,85.54,71.97,69.14,58.90,79.80,83.42,64.84\77.88,77.85,66.23,65.10,58.18,78.29,77.61,66.17\71.60,68.74,62.40,61.23,55.08,76.47,73.24,65.45\58.20,52.46,59.68,59.73,47.94,71.68,62.21,60.63)
matrix `scoreref01'=(95.65,92.18,82.51,76.26,63.52,83.93,86.47,68.29\93.93,88.34,81.75,75.54,62.35,84.51,88.19,69.94\92.71,89.80,79.63,73.89,63.12,85.24,87.26,69.28\89.25,87.09,75.50,70.70,62.48,83.24,86.71,68.19\79.99,78.78,68.12,65.51,59.14,80.69,80.19,68.52\73.69,71.24,64.37,61.71,56.39,77.84,76.05,67.84\62.40,56.67,61.72,59.20,50.86,73.80,64.38,65.29)
matrix `scoreref'=(84.45,81.21,73.39,69.13,59.96,81.55,82.13,68.47\87.07,83.86,75.98,70.07,62.23,84.08,85.41,71.42\82.22,78.96,71.18,68.33,58.03,79.41,79.34,65.96)
matrix `scorerefv1'=(11.78,15.33,17.21,13.93,14.16,14.43,20.73,15.28\9.64,21.30,19.63,15.89,16.72,19.05,24.18,15.83\11.08,23.63,21.00,16.20,16.65,18.97,26.12,16.70\14.92,26.35,22.09,17.41,16.24,17.01,23.15,16.23\20.48,32.67,22.24,17.93,16.89,20.35,32.04,17.40\22.78,36.05,24.06,19.08,18.03,21.94,33.89,16.60\27.44,40.86,24.38,17.61,18.86,24.08,41.43,20.03)
matrix `scorerefv0'=(9.10,21.65,21.66,17.69,18.10,22.35,29.58,17.32\14.19,28.28,21.28,16.66,18.28,20.57,28.19,18.06\14.81,25.19,21.25,17.64,18.55,20.97,29.37,17.92\19.11,29.40,23.90,18.60,17.84,21.44,31.24,16.66\21.49,33.02,24.10,18.78,18.22,23.46,34.89,18.03\23.42,38.17,23.94,17.67,17.59,22.46,37.41,18.21\25.70,39.18,23.40,18.08,17.98,24.06,39.97,18.98)
matrix `scorerefv01'=(10.33,19.46,20.21,17.00,16.94,20.00,26.80,16.83\12.44,25.45,20.60,16.31,17.69,19.96,16.51,17.18\13.19,24.43,21.15,16.95,17.66,20.02,27.85,17.40\17.39,27.92,23.25,18.06,17.41,19.64,27.65,16.76\21.11,32.83,23.29,18.37,17.61,22.16,33.63,17.88\23.27,37.40,24.09,18.28,17.83,22.29,36.13,17.77\26.85,40.16,23.92,17.83,18.62,24.13,40.67,20.04)
matrix `scorerefv'=(21.19,32.20,23.73,18.57,18.05,21.41,32.15,17.62\19.85,30.48,23.03,18.39,17.36,20.08,29.89,16.70\22.02,33.43,24.10,18.69,18.40,22.26,33.71,17.99)
tempname scorerefpf scorerefrp scorerefbp scorerefgh scorerefvt scorerefsf scorerefre scorerefmh
tempname scorerefpfv scorerefrpv scorerefbpv scorerefghv scorerefvtv scorerefsfv scorerefrev scorerefmhv
if "`age'"!=""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref0'[1,`c'] if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref0'[2,`c'] if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref0'[3,`c'] if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref0'[4,`c'] if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref0'[5,`c'] if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref0'[6,`c'] if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref0'[7,`c'] if `sexe'==0&`age'>=75
qui replace `scoreref`i''=`scoreref1'[1,`c'] if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref1'[2,`c'] if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref1'[3,`c'] if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref1'[4,`c'] if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref1'[5,`c'] if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref1'[6,`c'] if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref1'[7,`c'] if `sexe'==1&`age'>=75
qui gen `scoreref`i'v'=(`scorerefv0'[1,`c'])^2 if `sexe'==0&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv0'[2,`c'])^2 if `sexe'==0&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv0'[3,`c'])^2 if `sexe'==0&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv0'[4,`c'])^2 if `sexe'==0&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv0'[5,`c'])^2 if `sexe'==0&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv0'[6,`c'])^2 if `sexe'==0&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv0'[7,`c'])^2 if `sexe'==0&`age'>=75
qui replace `scoreref`i'v'=(`scorerefv1'[1,`c'])^2 if `sexe'==1&`age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv1'[2,`c'])^2 if `sexe'==1&`age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv1'[3,`c'])^2 if `sexe'==1&`age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv1'[4,`c'])^2 if `sexe'==1&`age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv1'[5,`c'])^2 if `sexe'==1&`age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv1'[6,`c'])^2 if `sexe'==1&`age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv1'[7,`c'])^2 if `sexe'==1&`age'>=75
local ++c
}
}
else if "`age'"!=""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref01'[1,`c'] if `age'>=18&`age'<25
qui replace `scoreref`i''=`scoreref01'[2,`c'] if `age'>=25&`age'<35
qui replace `scoreref`i''=`scoreref01'[3,`c'] if `age'>=35&`age'<45
qui replace `scoreref`i''=`scoreref01'[4,`c'] if `age'>=45&`age'<55
qui replace `scoreref`i''=`scoreref01'[5,`c'] if `age'>=55&`age'<65
qui replace `scoreref`i''=`scoreref01'[6,`c'] if `age'>=65&`age'<75
qui replace `scoreref`i''=`scoreref01'[7,`c'] if `age'>=75
qui gen `scoreref`i'v'=(`scorerefv01'[1,`c'])^2 if `age'>=18&`age'<25
qui replace `scoreref`i'v'=(`scorerefv01'[2,`c'])^2 if `age'>=25&`age'<35
qui replace `scoreref`i'v'=(`scorerefv01'[3,`c'])^2 if `age'>=35&`age'<45
qui replace `scoreref`i'v'=(`scorerefv01'[4,`c'])^2 if `age'>=45&`age'<55
qui replace `scoreref`i'v'=(`scorerefv01'[5,`c'])^2 if `age'>=55&`age'<65
qui replace `scoreref`i'v'=(`scorerefv01'[6,`c'])^2 if `age'>=65&`age'<75
qui replace `scoreref`i'v'=(`scorerefv01'[7,`c'])^2 if `age'>=75
local ++c
}
}
else if "`age'"==""&"`sexe'"!="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
qui gen `scoreref`i''=`scoreref'[2,`c'] if `sexe'==1
qui replace `scoreref`i''=`scoreref'[3,`c'] if `sexe'==0
qui gen `scoreref`i'v'=(`scorerefv'[2,`c'])^2 if `sexe'==1
qui replace `scoreref`i'v'=(`scorerefv'[3,`c'])^2 if `sexe'==0
local ++c
}
}
else if "`age'"==""&"`sexe'"=="" {
local c=1
foreach i in pf rp bp gh vt sf re mh {
gen `scoreref`i''=`scoreref'[1,`c']
gen `scoreref`i'v'=(`scorerefv'[1,`c'])^2
local ++c
}
}
tempname scorerefpfz scorerefrpz scorerefbpz scorerefghz scorerefvtz scorerefsfz scorerefrez scorerefmhz scorerefpcs scorerefmcs
tempname scorerefpfvz scorerefrpvz scorerefbpvz scorerefghvz scorerefvtvz scorerefsfvz scorerefrevz scorerefmhvz scorerefpcsv scorerefmcsv
qui gen `scorerefpfz'=(`scorerefpf'-84.52404)/22.89490
qui gen `scorerefrpz'=(`scorerefrp'-81.19907)/33.79729
qui gen `scorerefbpz'=(`scorerefbp'-75.49196)/23.55879
qui gen `scorerefghz'=(`scorerefgh'-72.21316)/20.16964
qui gen `scorerefvtz'=(`scorerefvt'-61.05453)/20.86942
qui gen `scorerefsfz'=(`scorerefsf'-83.59753)/22.37649
qui gen `scorerefrez'=(`scorerefre'-81.29467)/33.02717
qui gen `scorerefmhz'=(`scorerefmh'-74.84212)/18.01189
qui gen `scorerefpcs'=(`scorerefpfz'*0.42402+`scorerefrpz'*0.35119+`scorerefbpz'*0.31754+`scorerefghz'*0.24954+`scorerefvtz'*0.02877-`scorerefsfz'*0.0753-`scorerefrez'*0.19206-`scorerefmhz'*0.22069)*10+50
qui gen `scorerefmcs'=(-`scorerefpfz'*0.22999-`scorerefrpz'*0.12329-`scorerefbpz'*0.09731-`scorerefghz'*0.01571+`scorerefvtz'*0.23534+`scorerefsfz'*0.26876+`scorerefrez'*0.43407+`scorerefmhz'*0.48581)*10+50
qui gen `scorerefpfvz'=(`scorerefpfv')/22.89490^2
qui gen `scorerefrpvz'=(`scorerefrpv')/33.79729^2
qui gen `scorerefbpvz'=(`scorerefbpv')/23.55879^2
qui gen `scorerefghvz'=(`scorerefghv')/20.16964^2
qui gen `scorerefvtvz'=(`scorerefvtv')/20.86942^2
qui gen `scorerefsfvz'=(`scorerefsfv')/22.37649^2
qui gen `scorerefrevz'=(`scorerefrev')/33.02717^2
qui gen `scorerefmhvz'=(`scorerefmhv')/18.01189^2
qui gen `scorerefpcsv'=(`scorerefpfvz'*0.42402^2+`scorerefrpvz'*0.35119^2+`scorerefbpvz'*0.31754^2+`scorerefghvz'*0.24954^2+`scorerefvtvz'*0.02877^2-`scorerefsfvz'*0.0753^2-`scorerefrevz'*0.19206^2-`scorerefmhvz'*0.22069^2)*10^2
qui gen `scorerefmcsv'=(-`scorerefpfvz'*0.22999^2-`scorerefrpvz'*0.12329^2-`scorerefbpvz'*0.09731^2-`scorerefghvz'*0.01571^2+`scorerefvtvz'*0.23534^2+`scorerefsfvz'*0.26876^2+`scorerefrevz'*0.43407^2+`scorerefmhvz'*0.48581^2)*10^2
if "`saveref'"!="" {
local listmin pf rp bp gh vt sf re mh pcs mcs
local listmaj PF RP BP GH VT SF RE MH PCS MCS
local error=0
local list
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0&"`replace'"=="" {
local ++error
local list "`list' `saveref'`j'"
}
local ++c
}
local c=1
if `error'==0 {
foreach i in `listmin' {
local j:word `c' of `listmaj'
capture confirm variable `saveref'`i'
if _rc==0 {
qui replace `saveref'`i'=`scoreref`i''
}
else {
qui gen `saveref'`i'=`scoreref`i''
}
local ++c
}
}
else {
di in red "The variable(s) `list' already exist(s)"
}
}
if "`details'"!="" {
di "{hline 80}"
di in gr _col(12) "Sample" _col(51) "Reference"
di in gr "Dimension" _col(16) "N" _col(21) "Mean" _col(29) "s.d." _col(40) "Min-Max" _col(52) "Mean" _col(60) "s.d." _col(72) "p"
di "{hline 80}"
local listmin pf rp bp gh vt sf re mh pcs mcs sf12p sf12m
local listmaj PF RP BP GH VT SF RE MH PCS MCS SF12P SF12M
local c=1
foreach i in `listmin' {
local j:word `c' of `listmaj'
qui su `score`i''
local means`i'=r(mean)
local sds`i'=r(sd)
local mins`i'=r(min)
local maxs`i'=r(max)
local n`i'=r(N)
if "`i'"!="sf12p"&"`i'"!="sf12m" {
qui su `scoreref`i'' if `score`i''!=.
local meanr`i'=r(mean)
local sdr`i'=r(sd)
local vr`i'=(`sdr`i'')^2
qui su `scoreref`i'v' if `score`i''!=.
local meanvr`i'=r(mean)
local sdr`i'=sqrt(`vr`i''+`meanvr`i'')
*local minr`i'=r(min)
*local maxr`i'=r(max)
qui ttest `score`i''=`meanr`i''
local p`i'=r(p)
}
di in gr "`j'" in ye _col(12) %5.0f `n`i'' _col(20) %5.2f `means`i'' _col(28) %5.2f `sds`i'' _col(34) %6.2f `mins`i'' "-" %6.2f `maxs`i'' _col(51) %5.2f `meanr`i'' _col(59) %5.2f `sdr`i'' _col(67) %6.4f `p`i''
local ++c
}
di "{hline 80}"
*corr `scorepcs' `scoremcs' `scoresf12p' `scoresf12m'
*scatter `scorepcs' `scoresf12p' ,name(p)
*scatter `scoremcs' `scoresf12m' ,name(m)
*su `scoresf12p' `sf12p_1' `sf12p_2a' `sf12p_2b' `sf12p_3a' `sf12p_3b' `sf12p_4a' `sf12p_4b' `sf12p_5' `sf12p_6' `sf12p_7a' `sf12p_7b' `sf12p_7c'
*su `scoresf12m' `sf12m_1' `sf12m_2a' `sf12m_2b' `sf12m_3a' `sf12m_3b' `sf12m_4a' `sf12m_4b' `sf12m_5' `sf12m_6' `sf12m_7a' `sf12m_7b' `sf12m_7c'
}
if "`saveimp'"!="" {
*su
foreach i of numlist 1 3/36 {
local j:word `i' of `varlistsav'
*di "gen `saveimp'`j'=`imp'``i''"
capture confirm variable `saveimp'`j'
if _rc==0&"`replace'"=="" {
di in ye "The variable `saveimp'`j' already exists and cannot be replaced."
}
else if _rc==0&"`replace'"!="" {
qui replace `saveimp'`j'=`imp'``i''
}
else {
qui gen `saveimp'`j'=`imp'``i''
}
}
}
end

View File

@ -0,0 +1,762 @@
*! version 4.3 August 29, 2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model,
* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM)
*
* Version 1 : May 9, 2005 (Jean-Benoit Hardouin)
* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/
* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/
* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/
* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/
* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/
* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/
* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/
* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/
* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/
* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/
* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/
* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/
* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/
* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/
* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/
* Version 4.3 : August 29, 2019 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/
*
* 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@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2005-2006, 2008-2009, 2011, 20130 2018, 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
************************************************************************************************************/
program define simirt , rclass
version 8.0
syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc]
/********************************************************************************
TESTS
********************************************************************************/
if `group'<0|`group'>1 {
di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}"
error 198
exit
}
if "`clear'"==""&"`store'"=="" {
di in red "You must use at least one of these two options: clear and/or store."
error 198
exit
}
if "`dim'"!="" {
local nbdim:word count `dim'
if `nbdim'>2&"`covmatrix'"=="" {
di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it."
error 198
exit
}
if "`covmatrix'"!="" {
local nbrowcovm=rowsof(`covmatrix')
if `nbdim'!=`nbrowcovm' {
di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that."
error 198
exit
}
}
local nbitems=0
forvalues d=1/`nbdim' {
local dim`d':word `d' of `dim'
local nbitems=`nbitems'+`dim`d''
}
local dim=`nbdim'
if "`diff'"!="" {
local nbdiff:word count `diff'
local tmp:word 1 of `diff'
if "`tmp'"=="gauss"|"`tmp'"=="uniform" {
local typediff values
}
else if `nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
else if "`diff'"=="" {
local diff gauss
forvalues d=1/`dim' {
local diff `diff' 0 1
}
local typediff gauss
local nbdiff:word count `diff'
}
}
else if "`dim'"==""{
if "`diff'"==""&"`pcm'"=="" {
di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)."
error 198
exit
}
else if "`covmatrix'"!= "" {
local nbrowcovm=rowsof(`covmatrix')
if `nbrowcovm'>1 {
di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option."
error 198
exit
}
}
else if "`pcm'"!="" {
local nbitems=rowsof(`pcm')
local dim=1
local dim1=`nbitems'
}
else {
local nbdiff:word count `diff'
local nbitems=`nbdiff'
local dim=1
local dim1=`nbitems'
}
}
if (`group'!=0|`deltagroup'!=0)&`dim'!=1 {
di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data."
error 198
exit
}
if "`prefix'"=="" {
local prefix item
}
local nbprefix:word count `prefix'
if `nbprefix'!=`dim'&`nbprefix'!=1 {
di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it."
error 198
exit
}
if `nbprefix'==`dim' {
forvalues d=1/`dim' {
local prefix`d':word `d' of `prefix'
}
}
else {
forvalues d=1/`dim' {
local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
local prefix`d' `prefix'`tmp'
}
}
if "`covmatrix'"=="" {
tempname covmatrix2
local nbcov:word count `cov'
if `dim'==1 {
if "`cov'"=="" {
local cov=1
}
if `nbcov'>1 {
di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option."
error 198
exit
}
if `cov'<0 {
di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option."
error 198
}
matrix `covmatrix2'=(`cov')
}
else if `dim'==2 {
if `nbcov'!=3&`nbcov'>0 {
di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)."
error 198
exit
}
else if `nbcov'==0 {
if `dim'==1 {
local cov "1"
}
else if `dim'==2 {
local cov "1 1 0"
}
local nbcov:word count `cov'
}
if `nbcov'==3 {
local cov1:word 1 of `cov'
local cov2:word 2 of `cov'
local cov3:word 3 of `cov'
local rho=`cov3'/sqrt(`cov1'*`cov2')
if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 {
di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it."
error 198
exit
}
}
matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2')
}
local covmatrix `covmatrix2'
}
local nbmu:word count `mu'
if `nbmu'!=`dim'&`nbmu'!=0 {
di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')"
error 198
exit
}
local nbdisc:word count `disc'
if `nbdisc'!=`nbitems'&`nbdisc'!=0 {
di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmin:word count `pmin'
if `nbpmin'!=`nbitems'&`nbpmin'!=0 {
di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmax:word count `pmax'
if `nbpmax'!=`nbitems'&`nbpmax'!=0 {
di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbacc:word count `acc'
if `nbacc'!=`nbitems'&`nbacc'!=0 {
di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") {
di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option"
error 198
exit
}
if "`rsm2'"!=""&`dim'==1 {
di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension"
error 198
exit
}
if "`id'"=="" {
local id="id"
}
preserve
tempfile saveraschbin
capture qui save `saveraschbin'
/********************************************************************************
PARAMETERS
********************************************************************************/
local hour=real(substr("$S_TIME",1,2))
local min=real(substr("$S_TIME",4,2))
local sec=real(substr("$S_TIME",7,2))
local jour=real(substr("$S_DATE",1,2))
if "$seed"!="" {
global seed2=int($seed)
}
else {
global seed2=0
}
global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour'
while $seed>2^31-1 {
global seed=int($seed/231)
}
qui set seed $seed
if "`typediff'"=="uniform" {
if `nbdiff'==`=`dim'*2+1' {
local min`d':word `=(`d'-1)*2+2' of `diff'
local max`d':word `=(`d'-1)*2+3' of `diff'
}
else if `nbdiff'==1 {
local min`d'=-2
local max`d'=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)'
}
}
}
else if "`typediff'"=="gauss" {
if `nbdiff'==`=`dim'*2+1' {
forvalues d=1/`dim' {
local mean`d':word `=(`d'-1)*2+2' of `diff'
local var`d':word `=(`d'-1)*2+3' of `diff'
}
}
else if `nbdiff'==1 {
forvalues d=1/`dim' {
local mean`d'=0
local var`d'=1
}
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d''
local diff `diff' `tmp'
}
}
}
forvalues d=1/`dim' {
if "`rsm`d''"!="" {
local nbrsm`d':word count `rsm`d''
forvalues i=2/`=`nbrsm`d''+1' {
local rsm`d'`i':word `=`i'-1' of `rsm`d''
if "`threshold'"!=""&`rsm`d'`i''<0 {
di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive."
error 198
exit
}
}
}
}
if "`diff'"!=""&"`pcm'"=="" {
tempname pcm
qui matrix `pcm'=J(`nbitems',1,.)
forvalues j=1/`nbitems' {
local tmp:word `j' of `diff'
qui matrix `pcm'[`j',1]=`tmp'
}
}
tempname matmu matcov matdiff matdisc matpmin matpmax matacc
matrix define `matdiff'=J(`nbitems',1,0)
matrix define `matdisc'=J(`nbitems',1,0)
matrix define `matpmin'=J(`nbitems',1,0)
matrix define `matpmax'=J(`nbitems',1,0)
matrix define `matacc'=J(`nbitems',1,0)
matrix define `matmu'=J(`dim',1,0)
matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0)
forvalues i=1/`nbitems'{
if `nbdisc'!=0 {
local tmp:word `i' of `disc'
matrix `matdisc'[`i',1]=`tmp'
}
else {
matrix `matdisc'[`i',1]=1
}
}
if "`pcm'"==""|"`rsm1'"!="" {
tempname pcm
if "`rsm1'"=="" {
forvalues i=1/`nbitems' {
local tmp:word `i' of `diff'
matrix `matdiff'[`i',1]=`tmp'
}
matrix `pcm'=`matdiff'
}
else {
local moda1:word count `rsm1'
local moda2:word count `rsm2'
local nbmodas=max(`=`moda1'+1',`=`moda2'+1')
matrix `pcm'=J(`nbitems',`nbmodas',.)
forvalues i=1/`dim1' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm1'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
if "`rsm2'"!="" {
forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm2'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
}
}
}
local nbmodas=colsof(`pcm')
forvalues j=1/`nbitems' {
local pcmpj`j'k0=-999999999999999
forvalues k=1/`nbmodas' {
local pcmpj`j'k`k'=`pcm'[`j',`k']
if `pcmpj`j'k`k''!=. {
local nbmodas`j'=`k'
}
local tmp=`k'-1
if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' {
di in red "With the {hi:threshold} option, the difficulties of a given item must increase."
error 198
exit
}
}
}
forvalues i=1/`nbitems' {
if `nbpmin'!=0 {
local tmp:word `i' of `pmin'
matrix `matpmin'[`i',1]=`tmp'
}
else {
matrix `matpmin'[`i',1]=0
}
if `nbpmax'!=0 {
local tmp:word `i' of `pmax'
matrix `matpmax'[`i',1]=`tmp'
}
else {
matrix `matpmax'[`i',1]=1
}
if `nbacc'!=0 {
local tmp:word `i' of `acc'
matrix `matacc'[`i',1]=`tmp'
}
else {
matrix `matacc'[`i',1]=1
}
}
if "`covmatrix'"=="" {
tempname covmatrix
if `nbcov'==1 {
matrix `covmatrix'=(`cov')
}
if `nbcov'==3 {
local tmp1:word 1 of `cov'
local tmp2:word 2 of `cov'
local tmp12:word 3 of `cov'
matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2')
}
}
matrix `matcov'=`covmatrix'
if (`nbmu'==`dim') {
forvalues d=1/`dim' {
local tmp:word `d' of `mu'
matrix `matmu'[`d',1]=`tmp'
}
}
if `dim'==2 {
local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2])
}
/********************************************************************************
SIMULATION
********************************************************************************/
drop _all
qui set obs `=`nbobs'+2001'
qui gen `id'=_n
tempname graphobs
qui gen `graphobs'=`id'>`nbobs'
local names
forvalues d=1/`dim' {
qui gen x`d'=invnorm(uniform())
qui compress
local names `names' lt`d'
}
matrix Chol=cholesky(corr(`covmatrix'))
forvalues d=1/`dim' {
qui gen lt`d'=0
forvalues i=1/`d' {
qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i'
}
qui compress
}
qui drop x*
forvalues d=1/`dim' {
qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1]
qui compress
}
qui replace lt1=_n-`nbobs' if `graphobs'
qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs'
if `dim'==1&`group'!=0 {
if "`random'"=="" {
qui gen group=uniform()<`group'
}
else {
qui gen group=`id'<=`group'*`nbobs'
}
qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1
qui replace lt1=lt1-`deltagroup'*`group' if group==0
qui compress
}
di in gr "Number of individuals: " in ye `nbobs'
di
if "`threshold'"=="" {
local line di in gr "{hline 75}"
}
else {
local line di in gr "{hline 27}"
}
if "`threshold'"=="" {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc"
}
else {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty"
}
local dim0=0
local deb1=1
local fin0=0
local fin1=`dim1'
forvalues d=1/`dim' { /* FOREACH DIMENSION*/
local deb`d'=`fin`=`d'-1''+1
local fin`d'=`deb`d''+`dim`d''-1
`line'
local p=`d'-1
local q=1
forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/
qui compress
tempname prob`i'_`=`nbmodas`i''+1'
qui gen `prob`i'_`=`nbmodas`i''+1''=0
local tau0=0
local tau1=`pcm'[`i',1]
local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))"
forvalues k=2/`nbmodas`i'' {
local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k']
local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) "
}
if "`threshold'"=="" {
tempname icc`i'
qui gen `icc`i''=0
tempname proba`i'_0
gen `proba`i'_0'=1
forvalues k=`nbmodas`i''(-1)1 {
tempname prob`i'_`k' proba`i'_`k'
qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1]
qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k''
qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1''
qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k''
qui compress
if "`genproba'"!="" {
qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1''
}
}
if "`genicc'"!="" {
qui gen icc`i'=`icc`i''
}
qui gen `prefix`d''`q'=0
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
forvalues k=2/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
}
tempname uni
qui gen `uni'=uniform()
forvalues k=1/`nbmodas`i'' {
qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k''
qui compress
}
}
else { /*if "`threshold'"!=""*/
qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1]
local tmp=0
forvalues k=1/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
local tmp=`tmp'+`pcm'[`i',`k']
qui replace `prefix`d''`q'=`k' if lt`d'>`tmp'
qui compress
}
}
local q=`q'+1
}
}
`line'
di
/********************************************************************************
CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES
********************************************************************************/
set tracedepth 1
if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" {
label variable lt1 "Latent trait"
local dess
sort lt1
if "`draw'"!=""|"`drawall'"!="" {
local alldess
forvalues i=1/`dim1' {
if "`title'"=="" {
local title2="Category Probability Curves of the Item `i'"
}
else {
local title2="`title'"
}
local dess
local tauj`j'k0=0
forvalues k=`nbmodas`i''(-1)0 {
local dess `dess' (line `proba`i'_`k'' lt1)
label variable `proba`i'_`k'' "`k'"
}
graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace)
local alldess `alldess' `dess'
}
if "`drawall'"!="" {
graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace)
}
}
if "`icc'"!="" {
local hicc
forvalues i=1/`dim1' {
if "`titleicc'"=="" {
local title3="Item Characteristic Curve of the Item `i'"
}
else {
local title3="`title'"
}
graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace)
local hicc `hicc' (line `icc`i'' lt1)
label variable `icc`i'' "Item `i'"
}
graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace)
}
}
qui drop if `graphobs'
/********************************************************************************
DISPLAYING
********************************************************************************/
forvalues d=1/`dim' {
qui su lt`d'
local var_`d'=r(Var)
local mean_`d'=r(mean)
forvalues l=`=`d'+1'/`dim' {
qui corr lt`d' lt`l' ,cov
local cov_`d'_`l'=r(cov_12)
return scalar cov_`d'_`l'=`cov_`d'_`l''
}
return scalar mean_`d'=`mean_`d''
return scalar var_`d'=`var_`d''
}
forvalues d=1/`dim' {
forvalues l=`=`d'+1'/`dim' {
local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'')
return scalar corr_`d'_`l'=`corr_`d'_`l''
}
}
if `dim'==1&`group'!=0 {
qui su lt1 if group==0
local mean_0=r(mean)
qui su lt1 if group==1
local mean_1=r(mean)
local delta=`mean_1'-`mean_0'
}
return scalar nbobs=`nbobs'
tempname matcorr
matrix `matcorr'=corr(`matcov')
di in gr "{hline 50}"
di _col(1) in gr "Latent trait" _c
if `dim'==2 {
di in gr "s"_c
}
di in gr _col(30) "Expected" _col(42) "Observed"
di in gr "{hline 50}"
forvalues i=1/`dim' {
di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i''
di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i''
forvalues d=`=`i'+1'/`dim' {
di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d''
di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d''
}
di in gr "{hline 50}"
}
if `dim'==1&`group'!=0 {
di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0'
di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1'
qui count if group==1
local prop=r(N)/`nbobs'
di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop'
di in gr "{hline 50}"
}
/********************************************************************************
CLEAR AND/OR STORE
********************************************************************************/
qui compress
if "`clear'"!="" {
restore, not
preserve
}
if "`store'"!="" {
save "`store'",`replace'
}
if "`clear'"=="" {
capture use "`saveraschbin'",replace
}
end

View File

@ -0,0 +1,760 @@
*! version 4.1 December 17, 2013
*! Jean-Benoit Hardouin
************************************************************************************************************
* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model,
* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM)
*
* Version 1 : May 9, 2005 (Jean-Benoit Hardouin)
* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/
* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/
* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/
* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/
* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/
* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/
* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/
* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/
* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/
* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/
* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/
* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/
* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/
* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/
*
* 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@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2005-2006, 2008-2009, 2011, 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 simirt , rclass
version 8.0
syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc]
/********************************************************************************
TESTS
********************************************************************************/
if `group'<0|`group'>1 {
di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}"
error 198
exit
}
if "`clear'"==""&"`store'"=="" {
di in red "You must use at least one of these two options: clear and/or store."
error 198
exit
}
if "`dim'"!="" {
local nbdim:word count `dim'
if `nbdim'>2&"`covmatrix'"=="" {
di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it."
error 198
exit
}
if "`covmatrix'"!="" {
local nbrowcovm=rowsof(`covmatrix')
if `nbdim'!=`nbrowcovm' {
di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that."
error 198
exit
}
}
local nbitems=0
forvalues d=1/`nbdim' {
local dim`d':word `d' of `dim'
local nbitems=`nbitems'+`dim`d''
}
local dim=`nbdim'
if "`diff'"!="" {
local nbdiff:word count `diff'
local tmp:word 1 of `diff'
if "`tmp'"=="gauss"|"`tmp'"=="uniform" {
local typediff values
}
else if `nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
else if "`diff'"=="" {
local diff gauss
forvalues d=1/`dim' {
local diff `diff' 0 1
}
local typediff gauss
local nbdiff:word count `diff'
}
}
else if "`dim'"==""{
if "`diff'"==""&"`pcm'"=="" {
di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)."
error 198
exit
}
else if "`covmatrix'"!= "" {
local nbrowcovm=rowsof(`covmatrix')
if `nbrowcovm'>1 {
di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option."
error 198
exit
}
}
else if "`pcm'"!="" {
local nbitems=rowsof(`pcm')
local dim=1
local dim1=`nbitems'
}
else {
local nbdiff:word count `diff'
local nbitems=`nbdiff'
local dim=1
local dim1=`nbitems'
}
}
if (`group'!=0|`deltagroup'!=0)&`dim'!=1 {
di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data."
error 198
exit
}
if "`prefix'"=="" {
local prefix item
}
local nbprefix:word count `prefix'
if `nbprefix'!=`dim'&`nbprefix'!=1 {
di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it."
error 198
exit
}
if `nbprefix'==`dim' {
forvalues d=1/`dim' {
local prefix`d':word `d' of `prefix'
}
}
else {
forvalues d=1/`dim' {
local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
local prefix`d' `prefix'`tmp'
}
}
if "`covmatrix'"=="" {
tempname covmatrix2
local nbcov:word count `cov'
if `dim'==1 {
if "`cov'"=="" {
local cov=1
}
if `nbcov'>1 {
di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option."
error 198
exit
}
if `cov'<0 {
di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option."
error 198
}
matrix `covmatrix2'=(`cov')
}
else if `dim'==2 {
if `nbcov'!=3&`nbcov'>0 {
di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)."
error 198
exit
}
else if `nbcov'==0 {
if `dim'==1 {
local cov "1"
}
else if `dim'==2 {
local cov "1 1 0"
}
local nbcov:word count `cov'
}
if `nbcov'==3 {
local cov1:word 1 of `cov'
local cov2:word 2 of `cov'
local cov3:word 3 of `cov'
local rho=`cov3'/sqrt(`cov1'*`cov2')
if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 {
di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it."
error 198
exit
}
}
matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2')
}
local covmatrix `covmatrix2'
}
local nbmu:word count `mu'
if `nbmu'!=`dim'&`nbmu'!=0 {
di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')"
error 198
exit
}
local nbdisc:word count `disc'
if `nbdisc'!=`nbitems'&`nbdisc'!=0 {
di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmin:word count `pmin'
if `nbpmin'!=`nbitems'&`nbpmin'!=0 {
di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmax:word count `pmax'
if `nbpmax'!=`nbitems'&`nbpmax'!=0 {
di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbacc:word count `acc'
if `nbacc'!=`nbitems'&`nbacc'!=0 {
di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") {
di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option"
error 198
exit
}
if "`rsm2'"!=""&`dim'==1 {
di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension"
error 198
exit
}
if "`id'"=="" {
local id="id"
}
preserve
tempfile saveraschbin
capture qui save `saveraschbin'
/********************************************************************************
PARAMETERS
********************************************************************************/
local hour=real(substr("$S_TIME",1,2))
local min=real(substr("$S_TIME",4,2))
local sec=real(substr("$S_TIME",7,2))
local jour=real(substr("$S_DATE",1,2))
if "$seed"!="" {
global seed2=int($seed)
}
else {
global seed2=0
}
global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour'
while $seed>2^31-1 {
global seed=int($seed/231)
}
qui set seed $seed
if "`typediff'"=="uniform" {
if `nbdiff'==`=`dim'*2+1' {
local min`d':word `=(`d'-1)*2+2' of `diff'
local max`d':word `=(`d'-1)*2+3' of `diff'
}
else if `nbdiff'==1 {
local min`d'=-2
local max`d'=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)'
}
}
}
else if "`typediff'"=="gauss" {
if `nbdiff'==`=`dim'*2+1' {
forvalues d=1/`dim' {
local mean`d':word `=(`d'-1)*2+2' of `diff'
local var`d':word `=(`d'-1)*2+3' of `diff'
}
}
else if `nbdiff'==1 {
forvalues d=1/`dim' {
local mean`d'=0
local var`d'=1
}
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d''
local diff `diff' `tmp'
}
}
}
forvalues d=1/`dim' {
if "`rsm`d''"!="" {
local nbrsm`d':word count `rsm`d''
forvalues i=2/`=`nbrsm`d''+1' {
local rsm`d'`i':word `=`i'-1' of `rsm`d''
if "`threshold'"!=""&`rsm`d'`i''<0 {
di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive."
error 198
exit
}
}
}
}
if "`diff'"!=""&"`pcm'"=="" {
tempname pcm
qui matrix `pcm'=J(`nbitems',1,.)
forvalues j=1/`nbitems' {
local tmp:word `j' of `diff'
qui matrix `pcm'[`j',1]=`tmp'
}
}
tempname matmu matcov matdiff matdisc matpmin matpmax matacc
matrix define `matdiff'=J(`nbitems',1,0)
matrix define `matdisc'=J(`nbitems',1,0)
matrix define `matpmin'=J(`nbitems',1,0)
matrix define `matpmax'=J(`nbitems',1,0)
matrix define `matacc'=J(`nbitems',1,0)
matrix define `matmu'=J(`dim',1,0)
matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0)
forvalues i=1/`nbitems'{
if `nbdisc'!=0 {
local tmp:word `i' of `disc'
matrix `matdisc'[`i',1]=`tmp'
}
else {
matrix `matdisc'[`i',1]=1
}
}
if "`pcm'"==""|"`rsm1'"!="" {
tempname pcm
if "`rsm1'"=="" {
forvalues i=1/`nbitems' {
local tmp:word `i' of `diff'
matrix `matdiff'[`i',1]=`tmp'
}
matrix `pcm'=`matdiff'
}
else {
local moda1:word count `rsm1'
local moda2:word count `rsm2'
local nbmodas=max(`=`moda1'+1',`=`moda2'+1')
matrix `pcm'=J(`nbitems',`nbmodas',.)
forvalues i=1/`dim1' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm1'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
if "`rsm2'"!="" {
forvalues i=`dim1'+1/`=`dim1'+`dim2'' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`modamax'-1' {
local tmp:word `j' of `rsm2'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
}
}
}
local nbmodas=colsof(`pcm')
forvalues j=1/`nbitems' {
local pcmpj`j'k0=-999999999999999
forvalues k=1/`nbmodas' {
local pcmpj`j'k`k'=`pcm'[`j',`k']
if `pcmpj`j'k`k''!=. {
local nbmodas`j'=`k'
}
local tmp=`k'-1
if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' {
di in red "With the {hi:threshold} option, the difficulties of a given item must increase."
error 198
exit
}
}
}
forvalues i=1/`nbitems' {
if `nbpmin'!=0 {
local tmp:word `i' of `pmin'
matrix `matpmin'[`i',1]=`tmp'
}
else {
matrix `matpmin'[`i',1]=0
}
if `nbpmax'!=0 {
local tmp:word `i' of `pmax'
matrix `matpmax'[`i',1]=`tmp'
}
else {
matrix `matpmax'[`i',1]=1
}
if `nbacc'!=0 {
local tmp:word `i' of `acc'
matrix `matacc'[`i',1]=`tmp'
}
else {
matrix `matacc'[`i',1]=1
}
}
if "`covmatrix'"=="" {
tempname covmatrix
if `nbcov'==1 {
matrix `covmatrix'=(`cov')
}
if `nbcov'==3 {
local tmp1:word 1 of `cov'
local tmp2:word 2 of `cov'
local tmp12:word 3 of `cov'
matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2')
}
}
matrix `matcov'=`covmatrix'
if (`nbmu'==`dim') {
forvalues d=1/`dim' {
local tmp:word `d' of `mu'
matrix `matmu'[`d',1]=`tmp'
}
}
if `dim'==2 {
local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2])
}
/********************************************************************************
SIMULATION
********************************************************************************/
drop _all
qui set obs `=`nbobs'+2001'
qui gen `id'=_n
tempname graphobs
qui gen `graphobs'=`id'>`nbobs'
local names
forvalues d=1/`dim' {
qui gen x`d'=invnorm(uniform())
qui compress
local names `names' lt`d'
}
matrix Chol=cholesky(corr(`covmatrix'))
forvalues d=1/`dim' {
qui gen lt`d'=0
forvalues i=1/`d' {
qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i'
}
qui compress
}
qui drop x*
forvalues d=1/`dim' {
qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1]
qui compress
}
qui replace lt1=_n-`nbobs' if `graphobs'
qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs'
if `dim'==1&`group'!=0 {
if "`random'"=="" {
qui gen group=uniform()<`group'
}
else {
qui gen group=`id'<=`group'*`nbobs'
}
qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1
qui replace lt1=lt1-`deltagroup'*`group' if group==0
qui compress
}
di in gr "Number of individuals: " in ye `nbobs'
di
if "`threshold'"=="" {
local line di in gr "{hline 75}"
}
else {
local line di in gr "{hline 27}"
}
if "`threshold'"=="" {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc"
}
else {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty"
}
local dim0=0
local deb1=1
local fin0=0
local fin1=`dim1'
forvalues d=1/`dim' { /* FOREACH DIMENSION*/
local deb`d'=`fin`=`d'-1''+1
local fin`d'=`deb`d''+`dim`d''-1
`line'
local p=`d'-1
local q=1
forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/
qui compress
tempname prob`i'_`=`nbmodas`i''+1'
qui gen `prob`i'_`=`nbmodas`i''+1''=0
local tau0=0
local tau1=`pcm'[`i',1]
local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))"
forvalues k=2/`nbmodas`i'' {
local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k']
local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) "
}
if "`threshold'"=="" {
tempname icc`i'
qui gen `icc`i''=0
tempname proba`i'_0
gen `proba`i'_0'=1
forvalues k=`nbmodas`i''(-1)1 {
tempname prob`i'_`k' proba`i'_`k'
qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1]
qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k''
qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1''
qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k''
qui compress
if "`genproba'"!="" {
qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1''
}
}
if "`genicc'"!="" {
qui gen icc`i'=`icc`i''
}
qui gen `prefix`d''`q'=0
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
forvalues k=2/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
}
tempname uni
qui gen `uni'=uniform()
forvalues k=1/`nbmodas`i'' {
qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k''
qui compress
}
}
else { /*if "`threshold'"!=""*/
qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1]
local tmp=0
forvalues k=1/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
local tmp=`tmp'+`pcm'[`i',`k']
qui replace `prefix`d''`q'=`k' if lt`d'>`tmp'
qui compress
}
}
local q=`q'+1
}
}
`line'
di
/********************************************************************************
CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES
********************************************************************************/
set tracedepth 1
if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" {
label variable lt1 "Latent trait"
local dess
sort lt1
if "`draw'"!=""|"`drawall'"!="" {
local alldess
forvalues i=1/`dim1' {
if "`title'"=="" {
local title2="Category Probability Curves of the Item `i'"
}
else {
local title2="`title'"
}
local dess
local tauj`j'k0=0
forvalues k=`nbmodas`i''(-1)0 {
local dess `dess' (line `proba`i'_`k'' lt1)
label variable `proba`i'_`k'' "`k'"
}
graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace)
local alldess `alldess' `dess'
}
if "`drawall'"!="" {
graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace)
}
}
if "`icc'"!="" {
local hicc
forvalues i=1/`dim1' {
if "`titleicc'"=="" {
local title3="Item Characteristic Curve of the Item `i'"
}
else {
local title3="`title'"
}
graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace)
local hicc `hicc' (line `icc`i'' lt1)
label variable `icc`i'' "Item `i'"
}
graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace)
}
}
qui drop if `graphobs'
/********************************************************************************
DISPLAYING
********************************************************************************/
forvalues d=1/`dim' {
qui su lt`d'
local var_`d'=r(Var)
local mean_`d'=r(mean)
forvalues l=`=`d'+1'/`dim' {
qui corr lt`d' lt`l' ,cov
local cov_`d'_`l'=r(cov_12)
return scalar cov_`d'_`l'=`cov_`d'_`l''
}
return scalar mean_`d'=`mean_`d''
return scalar var_`d'=`var_`d''
}
forvalues d=1/`dim' {
forvalues l=`=`d'+1'/`dim' {
local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'')
return scalar corr_`d'_`l'=`corr_`d'_`l''
}
}
if `dim'==1&`group'!=0 {
qui su lt1 if group==0
local mean_0=r(mean)
qui su lt1 if group==1
local mean_1=r(mean)
local delta=`mean_1'-`mean_0'
}
return scalar nbobs=`nbobs'
tempname matcorr
matrix `matcorr'=corr(`matcov')
di in gr "{hline 50}"
di _col(1) in gr "Latent trait" _c
if `dim'==2 {
di in gr "s"_c
}
di in gr _col(30) "Expected" _col(42) "Observed"
di in gr "{hline 50}"
forvalues i=1/`dim' {
di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i''
di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i''
forvalues d=`=`i'+1'/`dim' {
di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d''
di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d''
}
di in gr "{hline 50}"
}
if `dim'==1&`group'!=0 {
di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0'
di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1'
qui count if group==1
local prop=r(N)/`nbobs'
di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop'
di in gr "{hline 50}"
}
/********************************************************************************
CLEAR AND/OR STORE
********************************************************************************/
qui compress
if "`clear'"!="" {
restore, not
preserve
}
if "`store'"!="" {
save "`store'",`replace'
}
if "`clear'"=="" {
use "`saveraschbin'",replace
}
end

View File

@ -0,0 +1,761 @@
*! version 4.2 June 19, 2018
*! Jean-Benoit Hardouin
************************************************************************************************************
* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model,
* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM)
*
* Version 1 : May 9, 2005 (Jean-Benoit Hardouin)
* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/
* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/
* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/
* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/
* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/
* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/
* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/
* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/
* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/
* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/
* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/
* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/
* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/
* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/
* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/
*
* 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@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2005-2006, 2008-2009, 2011, 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 simirt , rclass
version 8.0
syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc]
/********************************************************************************
TESTS
********************************************************************************/
if `group'<0|`group'>1 {
di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}"
error 198
exit
}
if "`clear'"==""&"`store'"=="" {
di in red "You must use at least one of these two options: clear and/or store."
error 198
exit
}
if "`dim'"!="" {
local nbdim:word count `dim'
if `nbdim'>2&"`covmatrix'"=="" {
di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it."
error 198
exit
}
if "`covmatrix'"!="" {
local nbrowcovm=rowsof(`covmatrix')
if `nbdim'!=`nbrowcovm' {
di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that."
error 198
exit
}
}
local nbitems=0
forvalues d=1/`nbdim' {
local dim`d':word `d' of `dim'
local nbitems=`nbitems'+`dim`d''
}
local dim=`nbdim'
if "`diff'"!="" {
local nbdiff:word count `diff'
local tmp:word 1 of `diff'
if "`tmp'"=="gauss"|"`tmp'"=="uniform" {
local typediff values
}
else if `nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
else if "`diff'"=="" {
local diff gauss
forvalues d=1/`dim' {
local diff `diff' 0 1
}
local typediff gauss
local nbdiff:word count `diff'
}
}
else if "`dim'"==""{
if "`diff'"==""&"`pcm'"=="" {
di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)."
error 198
exit
}
else if "`covmatrix'"!= "" {
local nbrowcovm=rowsof(`covmatrix')
if `nbrowcovm'>1 {
di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option."
error 198
exit
}
}
else if "`pcm'"!="" {
local nbitems=rowsof(`pcm')
local dim=1
local dim1=`nbitems'
}
else {
local nbdiff:word count `diff'
local nbitems=`nbdiff'
local dim=1
local dim1=`nbitems'
}
}
if (`group'!=0|`deltagroup'!=0)&`dim'!=1 {
di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data."
error 198
exit
}
if "`prefix'"=="" {
local prefix item
}
local nbprefix:word count `prefix'
if `nbprefix'!=`dim'&`nbprefix'!=1 {
di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it."
error 198
exit
}
if `nbprefix'==`dim' {
forvalues d=1/`dim' {
local prefix`d':word `d' of `prefix'
}
}
else {
forvalues d=1/`dim' {
local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
local prefix`d' `prefix'`tmp'
}
}
if "`covmatrix'"=="" {
tempname covmatrix2
local nbcov:word count `cov'
if `dim'==1 {
if "`cov'"=="" {
local cov=1
}
if `nbcov'>1 {
di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option."
error 198
exit
}
if `cov'<0 {
di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option."
error 198
}
matrix `covmatrix2'=(`cov')
}
else if `dim'==2 {
if `nbcov'!=3&`nbcov'>0 {
di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)."
error 198
exit
}
else if `nbcov'==0 {
if `dim'==1 {
local cov "1"
}
else if `dim'==2 {
local cov "1 1 0"
}
local nbcov:word count `cov'
}
if `nbcov'==3 {
local cov1:word 1 of `cov'
local cov2:word 2 of `cov'
local cov3:word 3 of `cov'
local rho=`cov3'/sqrt(`cov1'*`cov2')
if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 {
di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it."
error 198
exit
}
}
matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2')
}
local covmatrix `covmatrix2'
}
local nbmu:word count `mu'
if `nbmu'!=`dim'&`nbmu'!=0 {
di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')"
error 198
exit
}
local nbdisc:word count `disc'
if `nbdisc'!=`nbitems'&`nbdisc'!=0 {
di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmin:word count `pmin'
if `nbpmin'!=`nbitems'&`nbpmin'!=0 {
di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmax:word count `pmax'
if `nbpmax'!=`nbitems'&`nbpmax'!=0 {
di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbacc:word count `acc'
if `nbacc'!=`nbitems'&`nbacc'!=0 {
di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") {
di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option"
error 198
exit
}
if "`rsm2'"!=""&`dim'==1 {
di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension"
error 198
exit
}
if "`id'"=="" {
local id="id"
}
preserve
tempfile saveraschbin
capture qui save `saveraschbin'
/********************************************************************************
PARAMETERS
********************************************************************************/
local hour=real(substr("$S_TIME",1,2))
local min=real(substr("$S_TIME",4,2))
local sec=real(substr("$S_TIME",7,2))
local jour=real(substr("$S_DATE",1,2))
if "$seed"!="" {
global seed2=int($seed)
}
else {
global seed2=0
}
global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour'
while $seed>2^31-1 {
global seed=int($seed/231)
}
qui set seed $seed
if "`typediff'"=="uniform" {
if `nbdiff'==`=`dim'*2+1' {
local min`d':word `=(`d'-1)*2+2' of `diff'
local max`d':word `=(`d'-1)*2+3' of `diff'
}
else if `nbdiff'==1 {
local min`d'=-2
local max`d'=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)'
}
}
}
else if "`typediff'"=="gauss" {
if `nbdiff'==`=`dim'*2+1' {
forvalues d=1/`dim' {
local mean`d':word `=(`d'-1)*2+2' of `diff'
local var`d':word `=(`d'-1)*2+3' of `diff'
}
}
else if `nbdiff'==1 {
forvalues d=1/`dim' {
local mean`d'=0
local var`d'=1
}
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d''
local diff `diff' `tmp'
}
}
}
forvalues d=1/`dim' {
if "`rsm`d''"!="" {
local nbrsm`d':word count `rsm`d''
forvalues i=2/`=`nbrsm`d''+1' {
local rsm`d'`i':word `=`i'-1' of `rsm`d''
if "`threshold'"!=""&`rsm`d'`i''<0 {
di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive."
error 198
exit
}
}
}
}
if "`diff'"!=""&"`pcm'"=="" {
tempname pcm
qui matrix `pcm'=J(`nbitems',1,.)
forvalues j=1/`nbitems' {
local tmp:word `j' of `diff'
qui matrix `pcm'[`j',1]=`tmp'
}
}
tempname matmu matcov matdiff matdisc matpmin matpmax matacc
matrix define `matdiff'=J(`nbitems',1,0)
matrix define `matdisc'=J(`nbitems',1,0)
matrix define `matpmin'=J(`nbitems',1,0)
matrix define `matpmax'=J(`nbitems',1,0)
matrix define `matacc'=J(`nbitems',1,0)
matrix define `matmu'=J(`dim',1,0)
matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0)
forvalues i=1/`nbitems'{
if `nbdisc'!=0 {
local tmp:word `i' of `disc'
matrix `matdisc'[`i',1]=`tmp'
}
else {
matrix `matdisc'[`i',1]=1
}
}
if "`pcm'"==""|"`rsm1'"!="" {
tempname pcm
if "`rsm1'"=="" {
forvalues i=1/`nbitems' {
local tmp:word `i' of `diff'
matrix `matdiff'[`i',1]=`tmp'
}
matrix `pcm'=`matdiff'
}
else {
local moda1:word count `rsm1'
local moda2:word count `rsm2'
local nbmodas=max(`=`moda1'+1',`=`moda2'+1')
matrix `pcm'=J(`nbitems',`nbmodas',.)
forvalues i=1/`dim1' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm1'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
if "`rsm2'"!="" {
forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm2'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
}
}
}
local nbmodas=colsof(`pcm')
forvalues j=1/`nbitems' {
local pcmpj`j'k0=-999999999999999
forvalues k=1/`nbmodas' {
local pcmpj`j'k`k'=`pcm'[`j',`k']
if `pcmpj`j'k`k''!=. {
local nbmodas`j'=`k'
}
local tmp=`k'-1
if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' {
di in red "With the {hi:threshold} option, the difficulties of a given item must increase."
error 198
exit
}
}
}
forvalues i=1/`nbitems' {
if `nbpmin'!=0 {
local tmp:word `i' of `pmin'
matrix `matpmin'[`i',1]=`tmp'
}
else {
matrix `matpmin'[`i',1]=0
}
if `nbpmax'!=0 {
local tmp:word `i' of `pmax'
matrix `matpmax'[`i',1]=`tmp'
}
else {
matrix `matpmax'[`i',1]=1
}
if `nbacc'!=0 {
local tmp:word `i' of `acc'
matrix `matacc'[`i',1]=`tmp'
}
else {
matrix `matacc'[`i',1]=1
}
}
if "`covmatrix'"=="" {
tempname covmatrix
if `nbcov'==1 {
matrix `covmatrix'=(`cov')
}
if `nbcov'==3 {
local tmp1:word 1 of `cov'
local tmp2:word 2 of `cov'
local tmp12:word 3 of `cov'
matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2')
}
}
matrix `matcov'=`covmatrix'
if (`nbmu'==`dim') {
forvalues d=1/`dim' {
local tmp:word `d' of `mu'
matrix `matmu'[`d',1]=`tmp'
}
}
if `dim'==2 {
local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2])
}
/********************************************************************************
SIMULATION
********************************************************************************/
drop _all
qui set obs `=`nbobs'+2001'
qui gen `id'=_n
tempname graphobs
qui gen `graphobs'=`id'>`nbobs'
local names
forvalues d=1/`dim' {
qui gen x`d'=invnorm(uniform())
qui compress
local names `names' lt`d'
}
matrix Chol=cholesky(corr(`covmatrix'))
forvalues d=1/`dim' {
qui gen lt`d'=0
forvalues i=1/`d' {
qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i'
}
qui compress
}
qui drop x*
forvalues d=1/`dim' {
qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1]
qui compress
}
qui replace lt1=_n-`nbobs' if `graphobs'
qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs'
if `dim'==1&`group'!=0 {
if "`random'"=="" {
qui gen group=uniform()<`group'
}
else {
qui gen group=`id'<=`group'*`nbobs'
}
qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1
qui replace lt1=lt1-`deltagroup'*`group' if group==0
qui compress
}
di in gr "Number of individuals: " in ye `nbobs'
di
if "`threshold'"=="" {
local line di in gr "{hline 75}"
}
else {
local line di in gr "{hline 27}"
}
if "`threshold'"=="" {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc"
}
else {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty"
}
local dim0=0
local deb1=1
local fin0=0
local fin1=`dim1'
forvalues d=1/`dim' { /* FOREACH DIMENSION*/
local deb`d'=`fin`=`d'-1''+1
local fin`d'=`deb`d''+`dim`d''-1
`line'
local p=`d'-1
local q=1
forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/
qui compress
tempname prob`i'_`=`nbmodas`i''+1'
qui gen `prob`i'_`=`nbmodas`i''+1''=0
local tau0=0
local tau1=`pcm'[`i',1]
local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))"
forvalues k=2/`nbmodas`i'' {
local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k']
local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) "
}
if "`threshold'"=="" {
tempname icc`i'
qui gen `icc`i''=0
tempname proba`i'_0
gen `proba`i'_0'=1
forvalues k=`nbmodas`i''(-1)1 {
tempname prob`i'_`k' proba`i'_`k'
qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1]
qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k''
qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1''
qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k''
qui compress
if "`genproba'"!="" {
qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1''
}
}
if "`genicc'"!="" {
qui gen icc`i'=`icc`i''
}
qui gen `prefix`d''`q'=0
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
forvalues k=2/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
}
tempname uni
qui gen `uni'=uniform()
forvalues k=1/`nbmodas`i'' {
qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k''
qui compress
}
}
else { /*if "`threshold'"!=""*/
qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1]
local tmp=0
forvalues k=1/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
local tmp=`tmp'+`pcm'[`i',`k']
qui replace `prefix`d''`q'=`k' if lt`d'>`tmp'
qui compress
}
}
local q=`q'+1
}
}
`line'
di
/********************************************************************************
CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES
********************************************************************************/
set tracedepth 1
if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" {
label variable lt1 "Latent trait"
local dess
sort lt1
if "`draw'"!=""|"`drawall'"!="" {
local alldess
forvalues i=1/`dim1' {
if "`title'"=="" {
local title2="Category Probability Curves of the Item `i'"
}
else {
local title2="`title'"
}
local dess
local tauj`j'k0=0
forvalues k=`nbmodas`i''(-1)0 {
local dess `dess' (line `proba`i'_`k'' lt1)
label variable `proba`i'_`k'' "`k'"
}
graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace)
local alldess `alldess' `dess'
}
if "`drawall'"!="" {
graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace)
}
}
if "`icc'"!="" {
local hicc
forvalues i=1/`dim1' {
if "`titleicc'"=="" {
local title3="Item Characteristic Curve of the Item `i'"
}
else {
local title3="`title'"
}
graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace)
local hicc `hicc' (line `icc`i'' lt1)
label variable `icc`i'' "Item `i'"
}
graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace)
}
}
qui drop if `graphobs'
/********************************************************************************
DISPLAYING
********************************************************************************/
forvalues d=1/`dim' {
qui su lt`d'
local var_`d'=r(Var)
local mean_`d'=r(mean)
forvalues l=`=`d'+1'/`dim' {
qui corr lt`d' lt`l' ,cov
local cov_`d'_`l'=r(cov_12)
return scalar cov_`d'_`l'=`cov_`d'_`l''
}
return scalar mean_`d'=`mean_`d''
return scalar var_`d'=`var_`d''
}
forvalues d=1/`dim' {
forvalues l=`=`d'+1'/`dim' {
local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'')
return scalar corr_`d'_`l'=`corr_`d'_`l''
}
}
if `dim'==1&`group'!=0 {
qui su lt1 if group==0
local mean_0=r(mean)
qui su lt1 if group==1
local mean_1=r(mean)
local delta=`mean_1'-`mean_0'
}
return scalar nbobs=`nbobs'
tempname matcorr
matrix `matcorr'=corr(`matcov')
di in gr "{hline 50}"
di _col(1) in gr "Latent trait" _c
if `dim'==2 {
di in gr "s"_c
}
di in gr _col(30) "Expected" _col(42) "Observed"
di in gr "{hline 50}"
forvalues i=1/`dim' {
di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i''
di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i''
forvalues d=`=`i'+1'/`dim' {
di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d''
di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d''
}
di in gr "{hline 50}"
}
if `dim'==1&`group'!=0 {
di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0'
di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1'
qui count if group==1
local prop=r(N)/`nbobs'
di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop'
di in gr "{hline 50}"
}
/********************************************************************************
CLEAR AND/OR STORE
********************************************************************************/
qui compress
if "`clear'"!="" {
restore, not
preserve
}
if "`store'"!="" {
save "`store'",`replace'
}
if "`clear'"=="" {
use "`saveraschbin'",replace
}
end

View File

@ -0,0 +1,762 @@
*! version 4.3 August 29, 2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model,
* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM)
*
* Version 1 : May 9, 2005 (Jean-Benoit Hardouin)
* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/
* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/
* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/
* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/
* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/
* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/
* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/
* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/
* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/
* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/
* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/
* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/
* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/
* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/
* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/
* Version 4.3 : August 29, 2019 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/
*
* 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@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2005-2006, 2008-2009, 2011, 20130 2018, 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
************************************************************************************************************/
program define simirt , rclass
version 8.0
syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc]
/********************************************************************************
TESTS
********************************************************************************/
if `group'<0|`group'>1 {
di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}"
error 198
exit
}
if "`clear'"==""&"`store'"=="" {
di in red "You must use at least one of these two options: clear and/or store."
error 198
exit
}
if "`dim'"!="" {
local nbdim:word count `dim'
if `nbdim'>2&"`covmatrix'"=="" {
di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it."
error 198
exit
}
if "`covmatrix'"!="" {
local nbrowcovm=rowsof(`covmatrix')
if `nbdim'!=`nbrowcovm' {
di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that."
error 198
exit
}
}
local nbitems=0
forvalues d=1/`nbdim' {
local dim`d':word `d' of `dim'
local nbitems=`nbitems'+`dim`d''
}
local dim=`nbdim'
if "`diff'"!="" {
local nbdiff:word count `diff'
local tmp:word 1 of `diff'
if "`tmp'"=="gauss"|"`tmp'"=="uniform" {
local typediff values
}
else if `nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
else if "`diff'"=="" {
local diff gauss
forvalues d=1/`dim' {
local diff `diff' 0 1
}
local typediff gauss
local nbdiff:word count `diff'
}
}
else if "`dim'"==""{
if "`diff'"==""&"`pcm'"=="" {
di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)."
error 198
exit
}
else if "`covmatrix'"!= "" {
local nbrowcovm=rowsof(`covmatrix')
if `nbrowcovm'>1 {
di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option."
error 198
exit
}
}
else if "`pcm'"!="" {
local nbitems=rowsof(`pcm')
local dim=1
local dim1=`nbitems'
}
else {
local nbdiff:word count `diff'
local nbitems=`nbdiff'
local dim=1
local dim1=`nbitems'
}
}
if (`group'!=0|`deltagroup'!=0)&`dim'!=1 {
di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data."
error 198
exit
}
if "`prefix'"=="" {
local prefix item
}
local nbprefix:word count `prefix'
if `nbprefix'!=`dim'&`nbprefix'!=1 {
di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it."
error 198
exit
}
if `nbprefix'==`dim' {
forvalues d=1/`dim' {
local prefix`d':word `d' of `prefix'
}
}
else {
forvalues d=1/`dim' {
local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
local prefix`d' `prefix'`tmp'
}
}
if "`covmatrix'"=="" {
tempname covmatrix2
local nbcov:word count `cov'
if `dim'==1 {
if "`cov'"=="" {
local cov=1
}
if `nbcov'>1 {
di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option."
error 198
exit
}
if `cov'<0 {
di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option."
error 198
}
matrix `covmatrix2'=(`cov')
}
else if `dim'==2 {
if `nbcov'!=3&`nbcov'>0 {
di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)."
error 198
exit
}
else if `nbcov'==0 {
if `dim'==1 {
local cov "1"
}
else if `dim'==2 {
local cov "1 1 0"
}
local nbcov:word count `cov'
}
if `nbcov'==3 {
local cov1:word 1 of `cov'
local cov2:word 2 of `cov'
local cov3:word 3 of `cov'
local rho=`cov3'/sqrt(`cov1'*`cov2')
if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 {
di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it."
error 198
exit
}
}
matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2')
}
local covmatrix `covmatrix2'
}
local nbmu:word count `mu'
if `nbmu'!=`dim'&`nbmu'!=0 {
di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')"
error 198
exit
}
local nbdisc:word count `disc'
if `nbdisc'!=`nbitems'&`nbdisc'!=0 {
di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmin:word count `pmin'
if `nbpmin'!=`nbitems'&`nbpmin'!=0 {
di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmax:word count `pmax'
if `nbpmax'!=`nbitems'&`nbpmax'!=0 {
di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbacc:word count `acc'
if `nbacc'!=`nbitems'&`nbacc'!=0 {
di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") {
di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option"
error 198
exit
}
if "`rsm2'"!=""&`dim'==1 {
di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension"
error 198
exit
}
if "`id'"=="" {
local id="id"
}
preserve
tempfile saveraschbin
capture qui save `saveraschbin'
/********************************************************************************
PARAMETERS
********************************************************************************/
local hour=real(substr("$S_TIME",1,2))
local min=real(substr("$S_TIME",4,2))
local sec=real(substr("$S_TIME",7,2))
local jour=real(substr("$S_DATE",1,2))
if "$seed"!="" {
global seed2=int($seed)
}
else {
global seed2=0
}
global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour'
while $seed>2^31-1 {
global seed=int($seed/231)
}
qui set seed $seed
if "`typediff'"=="uniform" {
if `nbdiff'==`=`dim'*2+1' {
local min`d':word `=(`d'-1)*2+2' of `diff'
local max`d':word `=(`d'-1)*2+3' of `diff'
}
else if `nbdiff'==1 {
local min`d'=-2
local max`d'=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)'
}
}
}
else if "`typediff'"=="gauss" {
if `nbdiff'==`=`dim'*2+1' {
forvalues d=1/`dim' {
local mean`d':word `=(`d'-1)*2+2' of `diff'
local var`d':word `=(`d'-1)*2+3' of `diff'
}
}
else if `nbdiff'==1 {
forvalues d=1/`dim' {
local mean`d'=0
local var`d'=1
}
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d''
local diff `diff' `tmp'
}
}
}
forvalues d=1/`dim' {
if "`rsm`d''"!="" {
local nbrsm`d':word count `rsm`d''
forvalues i=2/`=`nbrsm`d''+1' {
local rsm`d'`i':word `=`i'-1' of `rsm`d''
if "`threshold'"!=""&`rsm`d'`i''<0 {
di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive."
error 198
exit
}
}
}
}
if "`diff'"!=""&"`pcm'"=="" {
tempname pcm
qui matrix `pcm'=J(`nbitems',1,.)
forvalues j=1/`nbitems' {
local tmp:word `j' of `diff'
qui matrix `pcm'[`j',1]=`tmp'
}
}
tempname matmu matcov matdiff matdisc matpmin matpmax matacc
matrix define `matdiff'=J(`nbitems',1,0)
matrix define `matdisc'=J(`nbitems',1,0)
matrix define `matpmin'=J(`nbitems',1,0)
matrix define `matpmax'=J(`nbitems',1,0)
matrix define `matacc'=J(`nbitems',1,0)
matrix define `matmu'=J(`dim',1,0)
matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0)
forvalues i=1/`nbitems'{
if `nbdisc'!=0 {
local tmp:word `i' of `disc'
matrix `matdisc'[`i',1]=`tmp'
}
else {
matrix `matdisc'[`i',1]=1
}
}
if "`pcm'"==""|"`rsm1'"!="" {
tempname pcm
if "`rsm1'"=="" {
forvalues i=1/`nbitems' {
local tmp:word `i' of `diff'
matrix `matdiff'[`i',1]=`tmp'
}
matrix `pcm'=`matdiff'
}
else {
local moda1:word count `rsm1'
local moda2:word count `rsm2'
local nbmodas=max(`=`moda1'+1',`=`moda2'+1')
matrix `pcm'=J(`nbitems',`nbmodas',.)
forvalues i=1/`dim1' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm1'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
if "`rsm2'"!="" {
forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm2'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
}
}
}
local nbmodas=colsof(`pcm')
forvalues j=1/`nbitems' {
local pcmpj`j'k0=-999999999999999
forvalues k=1/`nbmodas' {
local pcmpj`j'k`k'=`pcm'[`j',`k']
if `pcmpj`j'k`k''!=. {
local nbmodas`j'=`k'
}
local tmp=`k'-1
if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' {
di in red "With the {hi:threshold} option, the difficulties of a given item must increase."
error 198
exit
}
}
}
forvalues i=1/`nbitems' {
if `nbpmin'!=0 {
local tmp:word `i' of `pmin'
matrix `matpmin'[`i',1]=`tmp'
}
else {
matrix `matpmin'[`i',1]=0
}
if `nbpmax'!=0 {
local tmp:word `i' of `pmax'
matrix `matpmax'[`i',1]=`tmp'
}
else {
matrix `matpmax'[`i',1]=1
}
if `nbacc'!=0 {
local tmp:word `i' of `acc'
matrix `matacc'[`i',1]=`tmp'
}
else {
matrix `matacc'[`i',1]=1
}
}
if "`covmatrix'"=="" {
tempname covmatrix
if `nbcov'==1 {
matrix `covmatrix'=(`cov')
}
if `nbcov'==3 {
local tmp1:word 1 of `cov'
local tmp2:word 2 of `cov'
local tmp12:word 3 of `cov'
matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2')
}
}
matrix `matcov'=`covmatrix'
if (`nbmu'==`dim') {
forvalues d=1/`dim' {
local tmp:word `d' of `mu'
matrix `matmu'[`d',1]=`tmp'
}
}
if `dim'==2 {
local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2])
}
/********************************************************************************
SIMULATION
********************************************************************************/
drop _all
qui set obs `=`nbobs'+2001'
qui gen `id'=_n
tempname graphobs
qui gen `graphobs'=`id'>`nbobs'
local names
forvalues d=1/`dim' {
qui gen x`d'=invnorm(uniform())
qui compress
local names `names' lt`d'
}
matrix Chol=cholesky(corr(`covmatrix'))
forvalues d=1/`dim' {
qui gen lt`d'=0
forvalues i=1/`d' {
qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i'
}
qui compress
}
qui drop x*
forvalues d=1/`dim' {
qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1]
qui compress
}
qui replace lt1=_n-`nbobs' if `graphobs'
qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs'
if `dim'==1&`group'!=0 {
if "`random'"=="" {
qui gen group=uniform()<`group'
}
else {
qui gen group=`id'<=`group'*`nbobs'
}
qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1
qui replace lt1=lt1-`deltagroup'*`group' if group==0
qui compress
}
di in gr "Number of individuals: " in ye `nbobs'
di
if "`threshold'"=="" {
local line di in gr "{hline 75}"
}
else {
local line di in gr "{hline 27}"
}
if "`threshold'"=="" {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc"
}
else {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty"
}
local dim0=0
local deb1=1
local fin0=0
local fin1=`dim1'
forvalues d=1/`dim' { /* FOREACH DIMENSION*/
local deb`d'=`fin`=`d'-1''+1
local fin`d'=`deb`d''+`dim`d''-1
`line'
local p=`d'-1
local q=1
forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/
qui compress
tempname prob`i'_`=`nbmodas`i''+1'
qui gen `prob`i'_`=`nbmodas`i''+1''=0
local tau0=0
local tau1=`pcm'[`i',1]
local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))"
forvalues k=2/`nbmodas`i'' {
local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k']
local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) "
}
if "`threshold'"=="" {
tempname icc`i'
qui gen `icc`i''=0
tempname proba`i'_0
gen `proba`i'_0'=1
forvalues k=`nbmodas`i''(-1)1 {
tempname prob`i'_`k' proba`i'_`k'
qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1]
qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k''
qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1''
qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k''
qui compress
if "`genproba'"!="" {
qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1''
}
}
if "`genicc'"!="" {
qui gen icc`i'=`icc`i''
}
qui gen `prefix`d''`q'=0
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
forvalues k=2/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
}
tempname uni
qui gen `uni'=uniform()
forvalues k=1/`nbmodas`i'' {
qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k''
qui compress
}
}
else { /*if "`threshold'"!=""*/
qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1]
local tmp=0
forvalues k=1/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
local tmp=`tmp'+`pcm'[`i',`k']
qui replace `prefix`d''`q'=`k' if lt`d'>`tmp'
qui compress
}
}
local q=`q'+1
}
}
`line'
di
/********************************************************************************
CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES
********************************************************************************/
set tracedepth 1
if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" {
label variable lt1 "Latent trait"
local dess
sort lt1
if "`draw'"!=""|"`drawall'"!="" {
local alldess
forvalues i=1/`dim1' {
if "`title'"=="" {
local title2="Category Probability Curves of the Item `i'"
}
else {
local title2="`title'"
}
local dess
local tauj`j'k0=0
forvalues k=`nbmodas`i''(-1)0 {
local dess `dess' (line `proba`i'_`k'' lt1)
label variable `proba`i'_`k'' "`k'"
}
graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace)
local alldess `alldess' `dess'
}
if "`drawall'"!="" {
graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace)
}
}
if "`icc'"!="" {
local hicc
forvalues i=1/`dim1' {
if "`titleicc'"=="" {
local title3="Item Characteristic Curve of the Item `i'"
}
else {
local title3="`title'"
}
graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace)
local hicc `hicc' (line `icc`i'' lt1)
label variable `icc`i'' "Item `i'"
}
graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace)
}
}
qui drop if `graphobs'
/********************************************************************************
DISPLAYING
********************************************************************************/
forvalues d=1/`dim' {
qui su lt`d'
local var_`d'=r(Var)
local mean_`d'=r(mean)
forvalues l=`=`d'+1'/`dim' {
qui corr lt`d' lt`l' ,cov
local cov_`d'_`l'=r(cov_12)
return scalar cov_`d'_`l'=`cov_`d'_`l''
}
return scalar mean_`d'=`mean_`d''
return scalar var_`d'=`var_`d''
}
forvalues d=1/`dim' {
forvalues l=`=`d'+1'/`dim' {
local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'')
return scalar corr_`d'_`l'=`corr_`d'_`l''
}
}
if `dim'==1&`group'!=0 {
qui su lt1 if group==0
local mean_0=r(mean)
qui su lt1 if group==1
local mean_1=r(mean)
local delta=`mean_1'-`mean_0'
}
return scalar nbobs=`nbobs'
tempname matcorr
matrix `matcorr'=corr(`matcov')
di in gr "{hline 50}"
di _col(1) in gr "Latent trait" _c
if `dim'==2 {
di in gr "s"_c
}
di in gr _col(30) "Expected" _col(42) "Observed"
di in gr "{hline 50}"
forvalues i=1/`dim' {
di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i''
di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i''
forvalues d=`=`i'+1'/`dim' {
di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d''
di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d''
}
di in gr "{hline 50}"
}
if `dim'==1&`group'!=0 {
di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0'
di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1'
qui count if group==1
local prop=r(N)/`nbobs'
di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop'
di in gr "{hline 50}"
}
/********************************************************************************
CLEAR AND/OR STORE
********************************************************************************/
qui compress
if "`clear'"!="" {
restore, not
preserve
}
if "`store'"!="" {
save "`store'",`replace'
}
if "`clear'"=="" {
capture use "`saveraschbin'",replace
}
end

View File

@ -0,0 +1,764 @@
*! version 4.4 March 21, 2022
*! Jean-Benoit Hardouin
************************************************************************************************************
* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model,
* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM)
*
* Version 1 : May 9, 2005 (Jean-Benoit Hardouin)
* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/
* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/
* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/
* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/
* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/
* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/
* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/
* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/
* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/
* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/
* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/
* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/
* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/
* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/
* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/
* Version 4.3 : August 29, 2019 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/
* Version 4.4 : March 21, 2022 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/
*
* 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@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2005-2006, 2008-2009, 2011, 20130 2018, 2019, 2022 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 simirt , rclass
version 8.0
syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc]
/********************************************************************************
TESTS
********************************************************************************/
if `group'<0|`group'>1 {
di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}"
error 198
exit
}
if "`clear'"==""&"`store'"=="" {
di in red "You must use at least one of these two options: clear and/or store."
error 198
exit
}
if "`dim'"!="" {
local nbdim:word count `dim'
if `nbdim'>2&"`covmatrix'"=="" {
di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it."
error 198
exit
}
if "`covmatrix'"!="" {
local nbrowcovm=rowsof(`covmatrix')
if `nbdim'!=`nbrowcovm' {
di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that."
error 198
exit
}
}
local nbitems=0
forvalues d=1/`nbdim' {
local dim`d':word `d' of `dim'
local nbitems=`nbitems'+`dim`d''
}
local dim=`nbdim'
if "`diff'"!="" {
local nbdiff:word count `diff'
local tmp:word 1 of `diff'
if "`tmp'"=="gauss"|"`tmp'"=="uniform" {
local typediff values
}
else if `nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
else if "`diff'"=="" {
local diff gauss
forvalues d=1/`dim' {
local diff `diff' 0 1
}
local typediff gauss
local nbdiff:word count `diff'
}
}
else if "`dim'"==""{
if "`diff'"==""&"`pcm'"=="" {
di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)."
error 198
exit
}
else if "`covmatrix'"!= "" {
local nbrowcovm=rowsof(`covmatrix')
if `nbrowcovm'>1 {
di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option."
error 198
exit
}
}
else if "`pcm'"!="" {
local nbitems=rowsof(`pcm')
local dim=1
local dim1=`nbitems'
}
else {
local nbdiff:word count `diff'
local nbitems=`nbdiff'
local dim=1
local dim1=`nbitems'
}
}
if (`group'!=0|`deltagroup'!=0)&`dim'!=1 {
di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data."
error 198
exit
}
if "`prefix'"=="" {
local prefix item
}
local nbprefix:word count `prefix'
if `nbprefix'!=`dim'&`nbprefix'!=1 {
di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it."
error 198
exit
}
if `nbprefix'==`dim' {
forvalues d=1/`dim' {
local prefix`d':word `d' of `prefix'
}
}
else {
forvalues d=1/`dim' {
local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
local prefix`d' `prefix'`tmp'
}
}
if "`covmatrix'"=="" {
tempname covmatrix2
local nbcov:word count `cov'
if `dim'==1 {
if "`cov'"=="" {
local cov=1
}
if `nbcov'>1 {
di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option."
error 198
exit
}
if `cov'<0 {
di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option."
error 198
}
matrix `covmatrix2'=(`cov')
}
else if `dim'==2 {
if `nbcov'!=3&`nbcov'>0 {
di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)."
error 198
exit
}
else if `nbcov'==0 {
if `dim'==1 {
local cov "1"
}
else if `dim'==2 {
local cov "1 1 0"
}
local nbcov:word count `cov'
}
if `nbcov'==3 {
local cov1:word 1 of `cov'
local cov2:word 2 of `cov'
local cov3:word 3 of `cov'
local rho=`cov3'/sqrt(`cov1'*`cov2')
if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 {
di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it."
error 198
exit
}
}
matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2')
}
local covmatrix `covmatrix2'
}
local nbmu:word count `mu'
if `nbmu'!=`dim'&`nbmu'!=0 {
di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')"
error 198
exit
}
local nbdisc:word count `disc'
if `nbdisc'!=`nbitems'&`nbdisc'!=0 {
di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmin:word count `pmin'
if `nbpmin'!=`nbitems'&`nbpmin'!=0 {
di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmax:word count `pmax'
if `nbpmax'!=`nbitems'&`nbpmax'!=0 {
di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbacc:word count `acc'
if `nbacc'!=`nbitems'&`nbacc'!=0 {
di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") {
di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option"
error 198
exit
}
if "`rsm2'"!=""&`dim'==1 {
di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension"
error 198
exit
}
if "`id'"=="" {
local id="id"
}
preserve
tempfile saveraschbin
capture qui save `saveraschbin'
/********************************************************************************
PARAMETERS
********************************************************************************/
local hour=real(substr("$S_TIME",1,2))
local min=real(substr("$S_TIME",4,2))
local sec=real(substr("$S_TIME",7,2))
local jour=real(substr("$S_DATE",1,2))
if "$seed"!="" {
global seed2=int($seed)
}
else {
global seed2=0
}
global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour'
while $seed>2^31-1 {
global seed=int($seed/231)
}
qui set seed $seed
if "`typediff'"=="uniform" {
if `nbdiff'==`=`dim'*2+1' {
local min`d':word `=(`d'-1)*2+2' of `diff'
local max`d':word `=(`d'-1)*2+3' of `diff'
}
else if `nbdiff'==1 {
local min`d'=-2
local max`d'=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)'
}
}
}
else if "`typediff'"=="gauss" {
if `nbdiff'==`=`dim'*2+1' {
forvalues d=1/`dim' {
local mean`d':word `=(`d'-1)*2+2' of `diff'
local var`d':word `=(`d'-1)*2+3' of `diff'
}
}
else if `nbdiff'==1 {
forvalues d=1/`dim' {
local mean`d'=0
local var`d'=1
}
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d''
local diff `diff' `tmp'
}
}
}
forvalues d=1/`dim' {
if "`rsm`d''"!="" {
local nbrsm`d':word count `rsm`d''
forvalues i=2/`=`nbrsm`d''+1' {
local rsm`d'`i':word `=`i'-1' of `rsm`d''
if "`threshold'"!=""&`rsm`d'`i''<0 {
di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive."
error 198
exit
}
}
}
}
if "`diff'"!=""&"`pcm'"=="" {
tempname pcm
qui matrix `pcm'=J(`nbitems',1,.)
forvalues j=1/`nbitems' {
local tmp:word `j' of `diff'
qui matrix `pcm'[`j',1]=`tmp'
}
}
tempname matmu matcov matdiff matdisc matpmin matpmax matacc
matrix define `matdiff'=J(`nbitems',1,0)
matrix define `matdisc'=J(`nbitems',1,0)
matrix define `matpmin'=J(`nbitems',1,0)
matrix define `matpmax'=J(`nbitems',1,0)
matrix define `matacc'=J(`nbitems',1,0)
matrix define `matmu'=J(`dim',1,0)
matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0)
forvalues i=1/`nbitems'{
if `nbdisc'!=0 {
local tmp:word `i' of `disc'
matrix `matdisc'[`i',1]=`tmp'
}
else {
matrix `matdisc'[`i',1]=1
}
}
if "`pcm'"==""|"`rsm1'"!="" {
tempname pcm
if "`rsm1'"=="" {
forvalues i=1/`nbitems' {
local tmp:word `i' of `diff'
matrix `matdiff'[`i',1]=`tmp'
}
matrix `pcm'=`matdiff'
}
else {
local moda1:word count `rsm1'
local moda2:word count `rsm2'
local nbmodas=max(`=`moda1'+1',`=`moda2'+1')
matrix `pcm'=J(`nbitems',`nbmodas',.)
forvalues i=1/`dim1' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm1'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
if "`rsm2'"!="" {
forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm2'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
}
}
}
local nbmodas=colsof(`pcm')
forvalues j=1/`nbitems' {
local pcmpj`j'k0=-999999999999999
forvalues k=1/`nbmodas' {
local pcmpj`j'k`k'=`pcm'[`j',`k']
if `pcmpj`j'k`k''!=. {
local nbmodas`j'=`k'
}
local tmp=`k'-1
if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' {
di in red "With the {hi:threshold} option, the difficulties of a given item must increase."
error 198
exit
}
}
}
forvalues i=1/`nbitems' {
if `nbpmin'!=0 {
local tmp:word `i' of `pmin'
matrix `matpmin'[`i',1]=`tmp'
}
else {
matrix `matpmin'[`i',1]=0
}
if `nbpmax'!=0 {
local tmp:word `i' of `pmax'
matrix `matpmax'[`i',1]=`tmp'
}
else {
matrix `matpmax'[`i',1]=1
}
if `nbacc'!=0 {
local tmp:word `i' of `acc'
matrix `matacc'[`i',1]=`tmp'
}
else {
matrix `matacc'[`i',1]=1
}
}
if "`covmatrix'"=="" {
tempname covmatrix
if `nbcov'==1 {
matrix `covmatrix'=(`cov')
}
if `nbcov'==3 {
local tmp1:word 1 of `cov'
local tmp2:word 2 of `cov'
local tmp12:word 3 of `cov'
matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2')
}
}
matrix `matcov'=`covmatrix'
if (`nbmu'==`dim') {
forvalues d=1/`dim' {
local tmp:word `d' of `mu'
matrix `matmu'[`d',1]=`tmp'
}
}
if `dim'==2 {
local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2])
}
/********************************************************************************
SIMULATION
********************************************************************************/
drop _all
qui set obs `=`nbobs'+2001'
qui gen `id'=_n
tempname graphobs
qui gen `graphobs'=`id'>`nbobs'
local names
forvalues d=1/`dim' {
qui gen x`d'=invnorm(uniform())
qui compress
local names `names' lt`d'
}
matrix Chol=cholesky(corr(`covmatrix'))
forvalues d=1/`dim' {
qui gen lt`d'=0
forvalues i=1/`d' {
qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i'
}
qui compress
}
qui drop x*
forvalues d=1/`dim' {
qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1]
qui compress
}
qui replace lt1=_n-`nbobs' if `graphobs'
qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs'
if `dim'==1&`group'!=0 {
if "`random'"=="" {
qui gen group=uniform()<`group'
}
else {
qui gen group=`id'<=`group'*`nbobs'
}
qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1
qui replace lt1=lt1-`deltagroup'*`group' if group==0
qui compress
}
di in gr "Number of individuals: " in ye `nbobs'
di
if "`threshold'"=="" {
local line di in gr "{hline 75}"
}
else {
local line di in gr "{hline 27}"
}
if "`threshold'"=="" {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc"
}
else {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty"
}
local dim0=0
local deb1=1
local fin0=0
local fin1=`dim1'
forvalues d=1/`dim' { /* FOREACH DIMENSION*/
local deb`d'=`fin`=`d'-1''+1
local fin`d'=`deb`d''+`dim`d''-1
`line'
local p=`d'-1
local q=1
forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/
qui compress
tempname prob`i'_`=`nbmodas`i''+1'
qui gen `prob`i'_`=`nbmodas`i''+1''=0
local tau0=0
local tau1=`pcm'[`i',1]
local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))"
forvalues k=2/`nbmodas`i'' {
local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k']
local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) "
}
if "`threshold'"=="" {
tempname icc`i'
qui gen `icc`i''=0
tempname proba`i'_0
gen `proba`i'_0'=1
forvalues k=`nbmodas`i''(-1)1 {
tempname prob`i'_`k' proba`i'_`k'
qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1]
qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k''
qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1''
qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k''
qui compress
if "`genproba'"!="" {
qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1''
}
}
if "`genicc'"!="" {
qui gen icc`i'=`icc`i''
}
qui gen `prefix`d''`q'=0
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
forvalues k=2/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
}
tempname uni
qui gen `uni'=uniform()
forvalues k=1/`nbmodas`i'' {
qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k''
qui compress
}
}
else { /*if "`threshold'"!=""*/
qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1]
local tmp=0
forvalues k=1/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
local tmp=`tmp'+`pcm'[`i',`k']
qui replace `prefix`d''`q'=`k' if lt`d'>`tmp'
qui compress
}
}
local q=`q'+1
}
}
`line'
di
/********************************************************************************
CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES
********************************************************************************/
set tracedepth 1
if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" {
label variable lt1 "Latent trait"
local dess
sort lt1
if "`draw'"!=""|"`drawall'"!="" {
local alldess
forvalues i=1/`dim1' {
if "`title'"=="" {
local title2="Category Probability Curves of the Item `i'"
}
else {
local title2="`title'"
}
local dess
local tauj`j'k0=0
forvalues k=`nbmodas`i''(-1)0 {
local dess `dess' (line `proba`i'_`k'' lt1)
label variable `proba`i'_`k'' "`k'"
}
graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace)
local alldess `alldess' `dess'
}
if "`drawall'"!="" {
graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace)
}
}
if "`icc'"!="" {
local hicc
forvalues i=1/`dim1' {
if "`titleicc'"=="" {
local title3="Item Characteristic Curve of the Item `i'"
}
else {
local title3="`title'"
}
graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace)
local hicc `hicc' (line `icc`i'' lt1)
label variable `icc`i'' "Item `i'"
}
graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace)
}
}
qui drop if `graphobs'
/********************************************************************************
DISPLAYING
********************************************************************************/
forvalues d=1/`dim' {
qui su lt`d'
local var_`d'=r(Var)
local mean_`d'=r(mean)
forvalues l=`=`d'+1'/`dim' {
qui corr lt`d' lt`l' ,cov
local cov_`d'_`l'=r(cov_12)
return scalar cov_`d'_`l'=`cov_`d'_`l''
}
return scalar mean_`d'=`mean_`d''
return scalar var_`d'=`var_`d''
}
forvalues d=1/`dim' {
forvalues l=`=`d'+1'/`dim' {
local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'')
return scalar corr_`d'_`l'=`corr_`d'_`l''
}
}
if `dim'==1&`group'!=0 {
qui su lt1 if group==0
local mean_0=r(mean)
qui su lt1 if group==1
local mean_1=r(mean)
local delta=`mean_1'-`mean_0'
}
return scalar nbobs=`nbobs'
tempname matcorr
matrix `matcorr'=corr(`matcov')
di in gr "{hline 50}"
di _col(1) in gr "Latent trait" _c
if `dim'==2 {
di in gr "s"_c
}
di in gr _col(30) "Expected" _col(42) "Observed"
di in gr "{hline 50}"
forvalues i=1/`dim' {
di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i''
di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i''
forvalues d=`=`i'+1'/`dim' {
di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d''
di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d''
}
di in gr "{hline 50}"
}
if `dim'==1&`group'!=0 {
di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0'
di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1'
qui count if group==1
local prop=r(N)/`nbobs'
di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop'
di in gr "{hline 50}"
}
/********************************************************************************
CLEAR AND/OR STORE
********************************************************************************/
qui compress
if "`clear'"!="" {
restore, not
preserve
}
if "`store'"!="" {
keep id lt* item*
save "`store'",`replace'
}
if "`clear'"=="" {
capture use "`saveraschbin'",replace
}
end

View File

@ -0,0 +1,801 @@
*! version 4.5 March 21, 2022
*! Jean-Benoit Hardouin
************************************************************************************************************
* Simirt: Simulation of dichotomous or polytomous data following an IRT model (Rasch model,
* OPLM, Birnbaum model, 3-PLM, 4-PLM, 5-PAM, RSM,PCM)
*
* Version 1 : May 9, 2005 (Jean-Benoit Hardouin)
* Version 1.1 : December 8, 2005 (Jean-Benoit Hardouin) /*group and deltagroup options*/
* Version 2 : January 20, 2006 (Jean-Benoit Hardouin) /*Rating Scale model*/
* Version 2.1 : Februar 2, 2006 (Jean-Benoit Hardouin) /*Threshold variables*/
* Version 2.2 : Februar 8, 2006 (Jean-Benoit Hardouin) /*Correction of an error with the RSM model*/
* Version 2.3 : October 22, 2006 (Jean-Benoit Hardouin) /*The "real" rating scale model*/
* Version 2.4 : July 7, 2008 (Jean-Benoit Hardouin) /*Title for the graphs*/
* Version 3 : October 14, 2008 (Jean-Benoit Hardouin) /*3 dimensions + correction for the mu vector*/
* Version 3.1 : December 11, 2008 (Jean-Benoit Hardouin) /*remove an useless output*/
* Version 3.2 : November 26, 2009 (Jean-Benoit Hardouin) /*covmatrix option*/
* Version 3.3 : October 25, 2011 (Jean-Benoit Hardouin) /*pcm option*/
* Version 3.4 : May 7, 2013 (Jean-Benoit Hardouin) /*Minor corrections, norandom option*/
* Version 3.5 : May 16, 2013 (Jean-Benoit Hardouin) /*Minor corrections*/
* Version 4 : December 11, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*GPCM + genp, genicc, icc options*/
* Version 4.1 : December 17, 2013 (Jean-Benoit Hardouin, Myriam Blanchin) /*drawall option*/
* Version 4.2 : June 19, 2018 (Jean-Benoit Hardouin) /*correction of a small bug with rsm2 option*/
* Version 4.3 : August 29, 2019 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/
* Version 4.4 : March 21, 2022 (Jean-Benoit Hardouin) /*correction of a small bug with store option*/
*
* 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@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2005-2006, 2008-2009, 2011, 20130 2018, 2019, 2022 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 simirt , rclass
version 8.0
syntax [, NBObs(integer 2000) Dim(string) MU(string) COV(string) COVMatrix(string) DISc(string) DIFf(string) PMIN(string) PMAX(string) ACC(string) clear STOre(string) REPlace PREFix(string) DRAW drawall ICC GRoup(real 0) noRANDom DELtagroup(real 0) rsm1(string) rsm2(string) THReshold TITle(string) PCM(string) id(string) GENProba GENIcc]
/********************************************************************************
TESTS
********************************************************************************/
if `group'<0|`group'>1 {
di in red "{p}The {hi:group} option defines a probability. The values defined by this option must be greater (or equal) to 0 and lesser (or equal) to 1.{p_end}"
error 198
exit
}
if "`clear'"==""&"`store'"=="" {
di in red "You must use at least one of these two options: clear and/or store."
error 198
exit
}
if "`dim'"!="" {
local nbdim:word count `dim'
if `nbdim'>2&"`covmatrix'"=="" {
di in red "You can simulate data with one or two dimensions, and you have indicated `nbdim' dimensions in the {hi:dim} option. Please correct it."
error 198
exit
}
if "`covmatrix'"!="" {
local nbrowcovm=rowsof(`covmatrix')
if `nbdim'!=`nbrowcovm' {
di in red "{p 0 0 0}You define `nbdim' dimension(s) with the {cmd:dim} option and `nbrowcovm' dimension(s) with the {cmd:covmatrix} option. Please correct that."
error 198
exit
}
}
local nbitems=0
forvalues d=1/`nbdim' {
local dim`d':word `d' of `dim'
local nbitems=`nbitems'+`dim`d''
}
local dim=`nbdim'
if "`diff'"!="" {
local nbdiff:word count `diff'
local tmp:word 1 of `diff'
if "`tmp'"=="gauss"|"`tmp'"=="uniform" {
local typediff values
}
else if `nbdiff'!=`nbitems' {
di in red "You have indicated a number of difficulty parameters ({hi:diff} option) different of the number of items to simulate ({hi:dim} option). Please correct these options."
error 198
exit
}
}
else if "`diff'"=="" {
local diff gauss
forvalues d=1/`dim' {
local diff `diff' 0 1
}
local typediff gauss
local nbdiff:word count `diff'
}
}
else if "`dim'"==""{
if "`diff'"==""&"`pcm'"=="" {
di in red "{p 0 0 0}You must indicate the number of items to simulate with the {hi:dim}, the {hi:pcm} or the {hi:diff} option(s)."
error 198
exit
}
else if "`covmatrix'"!= "" {
local nbrowcovm=rowsof(`covmatrix')
if `nbrowcovm'>1 {
di in red "{p 0 0 0}You have define `nbrowcovm' dimensions with the {hi:covmatrix} option, but you do not affect each item to a specific dimension using the {hi:dim} option. Please define the {hi:dim} option."
error 198
exit
}
}
else if "`pcm'"!="" {
local nbitems=rowsof(`pcm')
local dim=1
local dim1=`nbitems'
}
else {
local nbdiff:word count `diff'
local nbitems=`nbdiff'
local dim=1
local dim1=`nbitems'
}
}
if (`group'!=0|`deltagroup'!=0)&`dim'!=1 {
di in red "The {hi:group} and the {hi:deltagroup} options are available only with unidimensional simulated data."
error 198
exit
}
if "`prefix'"=="" {
local prefix item
}
local nbprefix:word count `prefix'
if `nbprefix'!=`dim'&`nbprefix'!=1 {
di in red "{p 0 0 0}The {hi:prefix} option is incorrect because the number of defined prefixes (`nbprefix') is different of the number of dimensions (`dim'). Please correct it."
error 198
exit
}
if `nbprefix'==`dim' {
forvalues d=1/`dim' {
local prefix`d':word `d' of `prefix'
}
}
else {
forvalues d=1/`dim' {
local tmp:word `d' of A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
local prefix`d' `prefix'`tmp'
}
}
if "`covmatrix'"=="" {
tempname covmatrix2
local nbcov:word count `cov'
if `dim'==1 {
if "`cov'"=="" {
local cov=1
}
if `nbcov'>1 {
di in red "You simulate one dimension. You must indicate only the variance of the simulated latent trait in the {hi:cov} option."
error 198
exit
}
if `cov'<0 {
di in red "The variance of your latent trait can not be negative. Please correct your {hi:cov} option."
error 198
}
matrix `covmatrix2'=(`cov')
}
else if `dim'==2 {
if `nbcov'!=3&`nbcov'>0 {
di in red "You simulate two dimensions. You must indicate exactly 3 values in the {hi:cov} option (Variance of the first simulated latent trait, Variance of the second simulated latent trait, Covariance between the two simulated latent traits)."
error 198
exit
}
else if `nbcov'==0 {
if `dim'==1 {
local cov "1"
}
else if `dim'==2 {
local cov "1 1 0"
}
local nbcov:word count `cov'
}
if `nbcov'==3 {
local cov1:word 1 of `cov'
local cov2:word 2 of `cov'
local cov3:word 3 of `cov'
local rho=`cov3'/sqrt(`cov1'*`cov2')
if `cov1'<0|`cov2'<0|`rho'<-1|`rho'>1 {
di in red "Your covariance matrix defined by the {hi:cov} option is not correct. Please correct it."
error 198
exit
}
}
matrix `covmatrix2'=(`cov1' , `cov3' \ `cov3' , `cov2')
}
local covmatrix `covmatrix2'
}
local nbmu:word count `mu'
if `nbmu'!=`dim'&`nbmu'!=0 {
di in red "You must indicate as many values in the {hi:mu} option as the number of dimension(s) (`dim')"
error 198
exit
}
local nbdisc:word count `disc'
if `nbdisc'!=`nbitems'&`nbdisc'!=0 {
di in red "You must indicate as many values in the {hi:disc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmin:word count `pmin'
if `nbpmin'!=`nbitems'&`nbpmin'!=0 {
di in red "You must indicate as many values in the {hi:pmin} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbpmax:word count `pmax'
if `nbpmax'!=`nbitems'&`nbpmax'!=0 {
di in red "You must indicate as many values in the {hi:pmax} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
local nbacc:word count `acc'
if `nbacc'!=`nbitems'&`nbacc'!=0 {
di in red "You must indicate as many values in the {hi:acc} option as items defined by the {hi:dim} and the {hi:diff} options (`nbitems')"
error 198
exit
}
if ("`threshold'"!="")&("`disc'"!=""|"`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:threshold} option, you cannot define the {hi:disc}, {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:rsm1} and/or {hi:rsm2} option(s), you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`pcm'"!="")&("`pmin'"!=""|"`pmax'"!=""|"`acc'"!="") {
di in red "If you use the {hi:pcm} option, you cannot define the {hi:pmin}, {hi:pmax} or {hi:acc} options"
error 198
exit
}
if ("`rsm1'"!=""|"`rsm2'"!="")&("`pcm'"!="") {
di in red "You cannot use in the same time the {hi:rsm1} and/or {hi:rsm2} options with the {hi:pcm} option"
error 198
exit
}
if "`rsm2'"!=""&`dim'==1 {
di in red "You cannot define the {hi:rsm2} option if you simulate only one dimension"
error 198
exit
}
if "`id'"=="" {
local id="id"
}
preserve
tempfile saveraschbin
capture qui save `saveraschbin'
/********************************************************************************
PARAMETERS
********************************************************************************/
local hour=real(substr("$S_TIME",1,2))
local min=real(substr("$S_TIME",4,2))
local sec=real(substr("$S_TIME",7,2))
local jour=real(substr("$S_DATE",1,2))
if "$seed"!="" {
global seed2=int($seed)
}
else {
global seed2=0
}
global seed=$seed2+256484+`sec'*1000000+`min'*10000+`hour'*100+`jour'
while $seed>2^31-1 {
global seed=int($seed/231)
}
qui set seed $seed
if "`typediff'"=="uniform" {
if `nbdiff'==`=`dim'*2+1' {
local min`d':word `=(`d'-1)*2+2' of `diff'
local max`d':word `=(`d'-1)*2+3' of `diff'
}
else if `nbdiff'==1 {
local min`d'=-2
local max`d'=2
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local diff `diff' `=`min`d''+(`max`d''-`min`d'')*`i'/(`dim`d''+1)'
}
}
}
else if "`typediff'"=="gauss" {
if `nbdiff'==`=`dim'*2+1' {
forvalues d=1/`dim' {
local mean`d':word `=(`d'-1)*2+2' of `diff'
local var`d':word `=(`d'-1)*2+3' of `diff'
}
}
else if `nbdiff'==1 {
forvalues d=1/`dim' {
local mean`d'=0
local var`d'=1
}
}
else {
di in red "Your {hi:diff} option is uncorrect. Please correct it."
error 198
exit
}
local diff
forvalues d=1/`dim' {
forvalues i=1/`dim`d'' {
local tmp=invnorm(`i'/(`dim`d''+1))*sqrt(`var`d'')+`mean`d''
local diff `diff' `tmp'
}
}
}
forvalues d=1/`dim' {
if "`rsm`d''"!="" {
local nbrsm`d':word count `rsm`d''
forvalues i=2/`=`nbrsm`d''+1' {
local rsm`d'`i':word `=`i'-1' of `rsm`d''
if "`threshold'"!=""&`rsm`d'`i''<0 {
di in red "With the {hi:threshold} option, the numbers defined in the {hi:rsm1} and {hi:rsm2} options must be positive."
error 198
exit
}
}
}
}
if "`diff'"!=""&"`pcm'"=="" {
tempname pcm
qui matrix `pcm'=J(`nbitems',1,.)
forvalues j=1/`nbitems' {
local tmp:word `j' of `diff'
qui matrix `pcm'[`j',1]=`tmp'
}
}
tempname matmu matcov matdiff matdisc matpmin matpmax matacc
matrix define `matdiff'=J(`nbitems',1,0)
matrix define `matdisc'=J(`nbitems',1,0)
matrix define `matpmin'=J(`nbitems',1,0)
matrix define `matpmax'=J(`nbitems',1,0)
matrix define `matacc'=J(`nbitems',1,0)
matrix define `matmu'=J(`dim',1,0)
matrix define `matcov'=J(`=(`dim'+1)*`dim'/2',1,0)
forvalues i=1/`nbitems'{
if `nbdisc'!=0 {
local tmp:word `i' of `disc'
matrix `matdisc'[`i',1]=`tmp'
}
else {
matrix `matdisc'[`i',1]=1
}
}
if "`pcm'"==""|"`rsm1'"!="" {
tempname pcm
if "`rsm1'"=="" {
forvalues i=1/`nbitems' {
local tmp:word `i' of `diff'
matrix `matdiff'[`i',1]=`tmp'
}
matrix `pcm'=`matdiff'
}
else {
local moda1:word count `rsm1'
local moda2:word count `rsm2'
local nbmodas=max(`=`moda1'+1',`=`moda2'+1')
matrix `pcm'=J(`nbitems',`nbmodas',.)
forvalues i=1/`dim1' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm1'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
if "`rsm2'"!="" {
forvalues i=`=`dim1'+1'/`=`dim1'+`dim2'' {
local tmp:word `i' of `diff'
matrix `pcm'[`i',1]=`tmp'
forvalues j=1/`=`nbmodas'-1' {
local tmp:word `j' of `rsm2'
matrix `pcm'[`i',`=1+`j'']=`pcm'[`i',1]+`tmp'
}
}
}
}
}
local nbmodas=colsof(`pcm')
forvalues j=1/`nbitems' {
local pcmpj`j'k0=-999999999999999
forvalues k=1/`nbmodas' {
local pcmpj`j'k`k'=`pcm'[`j',`k']
if `pcmpj`j'k`k''!=. {
local nbmodas`j'=`k'
}
local tmp=`k'-1
if "`threshold'"!=""&`pcmpj`j'k`k''<`pcmpj`j'k`tmp'' {
di in red "With the {hi:threshold} option, the difficulties of a given item must increase."
error 198
exit
}
}
}
forvalues i=1/`nbitems' {
if `nbpmin'!=0 {
local tmp:word `i' of `pmin'
matrix `matpmin'[`i',1]=`tmp'
}
else {
matrix `matpmin'[`i',1]=0
}
if `nbpmax'!=0 {
local tmp:word `i' of `pmax'
matrix `matpmax'[`i',1]=`tmp'
}
else {
matrix `matpmax'[`i',1]=1
}
if `nbacc'!=0 {
local tmp:word `i' of `acc'
matrix `matacc'[`i',1]=`tmp'
}
else {
matrix `matacc'[`i',1]=1
}
}
if "`covmatrix'"=="" {
tempname covmatrix
if `nbcov'==1 {
matrix `covmatrix'=(`cov')
}
if `nbcov'==3 {
local tmp1:word 1 of `cov'
local tmp2:word 2 of `cov'
local tmp12:word 3 of `cov'
matrix `covmatrix'=(`tmp1',`tmp12'\`tmp12',`tmp2')
}
}
matrix `matcov'=`covmatrix'
if (`nbmu'==`dim') {
forvalues d=1/`dim' {
local tmp:word `d' of `mu'
matrix `matmu'[`d',1]=`tmp'
}
}
if `dim'==2 {
local corr=`covmatrix'[1,2]/sqrt(`covmatrix'[1,1]*`covmatrix'[2,2])
}
/********************************************************************************
SIMULATION
********************************************************************************/
drop _all
qui set obs `=`nbobs'+2001'
qui gen `id'=_n
tempname graphobs
qui gen `graphobs'=`id'>`nbobs'
local names
forvalues d=1/`dim' {
qui gen x`d'=invnorm(uniform())
qui compress
local names `names' lt`d'
}
matrix Chol=cholesky(corr(`covmatrix'))
forvalues d=1/`dim' {
qui gen lt`d'=0
forvalues i=1/`d' {
qui replace lt`d'=lt`d'+Chol[`d',`i']*x`i'
}
qui compress
}
qui drop x*
forvalues d=1/`dim' {
qui replace lt`d'=lt`d'*sqrt(`covmatrix'[`d',`d'])+`matmu'[`d',1]
qui compress
}
qui replace lt1=_n-`nbobs' if `graphobs'
qui replace lt1=(lt1-1001)/1000*4*sqrt(`covmatrix'[1,1])+`matmu'[1,1] if `graphobs'
if `dim'==1&`group'!=0 {
if "`random'"=="" {
qui gen group=uniform()<`group'
}
else {
qui gen group=`id'<=`group'*`nbobs'
}
qui replace lt1=lt1+`deltagroup'*(1-`group') if group==1
qui replace lt1=lt1-`deltagroup'*`group' if group==0
qui compress
}
di in gr "Number of individuals: " in ye `nbobs'
di
if "`threshold'"=="" {
local line di in gr "{hline 75}"
}
else {
local line di in gr "{hline 27}"
}
if "`threshold'"=="" {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty" _col(34) "Discr." _col(45) "Pmin" _col(58) "Pmax" _col(73) "Acc"
}
else {
`line'
di _col(1) in gr "Items" _col(18) "Difficulty"
}
local dim0=0
local deb1=1
local fin0=0
local fin1=`dim1'
forvalues d=1/`dim' { /* FOREACH DIMENSION*/
local deb`d'=`fin`=`d'-1''+1
local fin`d'=`deb`d''+`dim`d''-1
`line'
local p=`d'-1
local q=1
forvalues i=`deb`d''/`fin`d'' { /*FOREACH ITEM*/
qui compress
tempname prob`i'_`=`nbmodas`i''+1' est`i'
qui gen `prob`i'_`=`nbmodas`i''+1''=0
qui gen `est`i''=.
local tau0=0
local tau1=`pcm'[`i',1]
local D "1+exp(`matdisc'[`i',1]*(lt`d'-`tau1'))"
forvalues k=2/`nbmodas`i'' {
local tau`k'=`tau`=`k'-1''+`pcm'[`i',`k']
local D "`D'+exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k'')) "
}
if "`threshold'"=="" {
tempname icc`i'
qui gen `icc`i''=0
tempname proba`i'_0 best`i'_0
gen `proba`i'_0'=1
forvalues k=`nbmodas`i''(-1)1 {
tempname prob`i'_`k' proba`i'_`k' best`i'_`k'
qui gen `proba`i'_`k''=`matpmin'[`i',1]+(`matpmax'[`i',1]-`matpmin'[`i',1])*(exp(`matdisc'[`i',1]*(`k'*lt`d'-`tau`k''))/(`D'))^`matacc'[`i',1]
qui replace `proba`i'_0'=`proba`i'_0'-`proba`i'_`k''
qui gen `prob`i'_`k''=`proba`i'_`k''+`prob`i'_`=`k'+1''
/************AJOUT 13/7/22**********/
qui gen `best`i'_`k''=`proba`i'_`k''*normalden(lt`d',`matmu'[1,1],sqrt(`covmatrix'[1,1]))
qui su `best`i'_`k''
qui su lt`d' if round(`best`i'_`k'',0.001)==round(`r(max)',0.001)
local bestloc`i'_`k'=r(mean)
di "Best location for item `i' category `k' : `bestloc`i'_`k''"
*qui replace `est`i''=`bestloc_`k'' if ``i''==`k'
/************FIN AJOUT 13/7/22**********/
qui replace `icc`i''=`icc`i''+`k'*`proba`i'_`k''
qui compress
if "`genproba'"!="" {
qui gen proba`i'_`k'=`prob`i'_`k''-`prob`i'_`=`k'+1''
}
}
/************AJOUT 13/7/22**********/
qui gen `best`i'_0'=`proba`i'_0'*normalden(lt`d',`matmu'[1,1],sqrt(`covmatrix'[1,1]))
qui su `best`i'_0'
qui su lt`d' if round(`best`i'_0',0.001)==round(`r(max)',0.001)
local bestloc`i'_0=r(mean)
di "Best location for item `i' category 0 : `bestloc_0'"
*qui replace `est`i''=`bestloc_0' if `i'==0
*corr `est`i'' lt1
/************FIN AJOUT 13/7/22**********/
if "`genicc'"!="" {
qui gen icc`i'=`icc`i''
}
qui gen `prefix`d''`q'=0
di _col(1) in gr "`prefix`d''`q'" _col(20) in ye %8.4f `pcm'[`i',1] _col(32) %8.4f `matdisc'[`i',1] _col(44) %6.4f `matpmin'[`i',1] _col(56) %6.4f `matpmax'[`i',1] _col(68) %8.4f `matacc'[`i',1]
forvalues k=2/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
}
tempname uni
qui gen `uni'=uniform()
forvalues k=1/`nbmodas`i'' {
qui replace `prefix`d''`q'=`k' if `uni'<=`prob`i'_`k''
qui compress
}
forvalues k=0/`nbmodas`i'' {
qui replace `est`i''=`bestloc`i'_`k'' if `prefix`d''`q'==`k'
}
su lt1 `est`i''
corr lt1 `est`i''
}
else { /*if "`threshold'"!=""*/
qui gen `prefix`d''`q'=lt`d'>`pcm'[`i',1]
local tmp=0
forvalues k=1/`nbmodas`i'' {
di _col(1) in gr "`prefix`d''`q'_`k'" _col(20) in ye %8.4f `pcm'[`i',`k']
local tmp=`tmp'+`pcm'[`i',`k']
qui replace `prefix`d''`q'=`k' if lt`d'>`tmp'
qui compress
}
}
local q=`q'+1
}
}
`line'
di
/********************************************************************************
CATEGORIES PROBABILITY CURVES and ITEMS CHARACTERISTIC CURVES
********************************************************************************/
set tracedepth 1
if "`draw'"!=""|"`icc'"!=""|"`drawall'"!="" {
label variable lt1 "Latent trait"
local dess
/************AJOUT 13/7/22**********/
local dessbest
/************FIN AJOUT 13/7/22**********/
sort lt1
if "`draw'"!=""|"`drawall'"!="" {
local alldess
forvalues i=1/`dim1' {
if "`title'"=="" {
local title2="Category Probability Curves of the Item `i'"
}
else {
local title2="`title'"
}
local dess
/************AJOUT 13/7/22**********/
local dessbest
/************FIN AJOUT 13/7/22**********/
local tauj`j'k0=0
forvalues k=`nbmodas`i''(-1)0 {
local dess `dess' (line `proba`i'_`k'' lt1)
/************AJOUT 13/7/22**********/
local dessbest `dessbest' (line `best`i'_`k'' lt1)
/************FIN AJOUT 13/7/22**********/
label variable `proba`i'_`k'' "`k'"
}
graph twoway `dess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(item`i',replace)
local alldess `alldess' `dess'
/************AJOUT 13/7/22**********/
graph twoway `dessbest' , ylabel(0(.25)1) legend(on) ytitle("Likelihood of latent trait as a fonction of the responses") title("`title2'") name(item`i',replace)
/************FIN AJOUT 13/7/22**********/
}
if "`drawall'"!="" {
graph twoway `alldess' , ylabel(0(.25)1) legend(on) ytitle("Probability of response to each modality") title("`title2'") name(all,replace)
}
}
if "`icc'"!="" {
local hicc
forvalues i=1/`dim1' {
if "`titleicc'"=="" {
local title3="Item Characteristic Curve of the Item `i'"
}
else {
local title3="`title'"
}
graph twoway (line `icc`i'' lt1) if `graphobs', ylabel(0(1)`nbmodas') legend(off) ytitle("Expected response") title("`title3'") name(iccitem`i',replace)
local hicc `hicc' (line `icc`i'' lt1)
label variable `icc`i'' "Item `i'"
}
graph twoway `hicc' if `graphobs', ylabel(0(1)`nbmodas') legend(on) ytitle("Expected response") title("Item Characteristic Curves") name(icc,replace)
}
}
qui drop if `graphobs'
/********************************************************************************
DISPLAYING
********************************************************************************/
forvalues d=1/`dim' {
qui su lt`d'
local var_`d'=r(Var)
local mean_`d'=r(mean)
forvalues l=`=`d'+1'/`dim' {
qui corr lt`d' lt`l' ,cov
local cov_`d'_`l'=r(cov_12)
return scalar cov_`d'_`l'=`cov_`d'_`l''
}
return scalar mean_`d'=`mean_`d''
return scalar var_`d'=`var_`d''
}
forvalues d=1/`dim' {
forvalues l=`=`d'+1'/`dim' {
local corr_`d'_`l'=`cov_`d'_`l''/sqrt(`var_`d''*`var_`l'')
return scalar corr_`d'_`l'=`corr_`d'_`l''
}
}
if `dim'==1&`group'!=0 {
qui su lt1 if group==0
local mean_0=r(mean)
qui su lt1 if group==1
local mean_1=r(mean)
local delta=`mean_1'-`mean_0'
}
return scalar nbobs=`nbobs'
tempname matcorr
matrix `matcorr'=corr(`matcov')
di in gr "{hline 50}"
di _col(1) in gr "Latent trait" _c
if `dim'==2 {
di in gr "s"_c
}
di in gr _col(30) "Expected" _col(42) "Observed"
di in gr "{hline 50}"
forvalues i=1/`dim' {
di _col(1) in gr "Mean(lt`i')" _col(30) in ye %8.4f `matmu'[`i',1] _col(42) %8.4f `mean_`i''
di _col(1) in gr "Variance(lt`i')" _col(30) in ye %8.4f `matcov'[`i',`i'] _col(42) %8.4f `var_`i''
forvalues d=`=`i'+1'/`dim' {
di _col(1) in gr "Covariance `i'_`d'" _col(30) in ye %8.4f `matcov'[`i',`d'] _col(42) %8.4f `cov_`i'_`d''
di _col(1) in gr "Correlation `i'_`d'" _col(31) in ye %7.4f `matcorr'[`i',`d'] _col(43) %7.4f `corr_`i'_`d''
}
di in gr "{hline 50}"
}
if `dim'==1&`group'!=0 {
di _col(1) in gr "Mean(lt1) group 0" _col(30) in ye %8.4f `matmu'[1,1]-`deltagroup'*`group' _col(42) %8.4f `mean_0'
di _col(1) in gr "Mean(lt1) group 1" _col(30) in ye %8.4f `matmu'[1,1]+`deltagroup'*(1-`group') _col(42) %8.4f `mean_1'
qui count if group==1
local prop=r(N)/`nbobs'
di _col(1) in gr "Proportion group 1" _col(30) in ye %8.4f `group' _col(42) %8.4f `prop'
di in gr "{hline 50}"
}
/********************************************************************************
CLEAR AND/OR STORE
********************************************************************************/
qui compress
if "`clear'"!="" {
restore, not
preserve
}
if "`store'"!="" {
keep id lt* item*
save "`store'",`replace'
}
if "`clear'"=="" {
capture use "`saveraschbin'",replace
}
end

View File

@ -0,0 +1,185 @@
{smcl}
{* 7May2013}{...}
{hline}
help for {hi:simirt}{right:Jean-Benoit Hardouin}
{hline}
{title:Simulation of IRT models}
{p 8 14 2}{cmd:simirt} [, {cmdab:nbo:bs}({it:#})
{cmdab:d:im}({it:# [#] [#]...}) {cmdab:mu}({it:# [#] [#]...}) {cmdab:cov}({it:# [# #]}) {cmdab:covm:atrix}({it:matrix})
{cmdab:dif:f}({it:list_of_values_or_expression}) {cmdab:pcm}({it:matrix}) {cmdab:dis:c}({it:list_of_values})
{cmdab:pmin}({it:list_of_values}) {cmdab:pmax}({it:list_of_values})
{cmdab:acc}({it:list_of_values})
{cmdab:rsm1}({it:list_of_values})
{cmdab:rsm2}({it:list_of_values})
{cmdab:thr:eshold}
{cmdab:clear} {cmdab:sto:re}({it:filename}) {cmdab:id}({it:newvarname})
{cmdab:rep:lace} {cmdab:pref:ix}({it:string}) {cmdab:draw} {cmdab:tit:le}({it:string})
{cmdab:gr:oup}({it:#}) {cmdab:norand:om} {cmdab:del:tagroup}({it:#})])
{title:Description}
{p 4 8 2}{cmd:simirt} allows creating a new dataset of responses
to items simulated by an unidimensional IRT model. The model can be
dichotomous (Rasch, OPLM, Birnbaum, 3PLM, 4PLM, 5PAM) or polytomous (Rating
Scale Model-RSM). It is possible to simulate two sets of items linked, for
each of them, to a specific latent trait (who can be correlated).
{title:Options}
{p 4 8 2}{cmd:nbobs}({it:#}) specifies the number of individuals to simulate.
By default, 2000 individuals are simulated.
{p 4 8 2}{cmd:dim}({it:# [#] [#]...}) specifies the number of items linked to the first
latent trait (and optionally to the second one and so on). If this option is not defined,
the {cmd:simirt} command simulates only one latent trait with a number of items
equal to the number of values defined in the {cmd:diff} or in the {cmd:pcm} option (at least one of
these three options must be defined).
{p 4 8 2}{cmd:mu}({it:# [#]}) specifies the mean(s) of each simulated latent
trait(s).
{p 4 8 2}{cmd:cov}({it:# [# #]}) defines the covariance matrix of the latent
trait(s). If there is only one latent, {cmd:cov} is composed of the variance of
this one, else, {cmd:cov} is composed of the variance of the first latent,
followed by the variance of the second latent trait, and of the covariance.
{p 4 8 2}{cmd:covmatrix}({it:matrix}) directly defines the covariance matrix of the latent
trait(s). This option is required instead of the {cmd:cov} option as soon as the number
of dimensions is greater than 2 (but this option could be used for one or two dimensions).
{p 4 8 2}{cmd:diff}({it:list_of_values_or_expression}) defines the values of the
difficulty parameters as a list of values (with a number of elements equal to
the total number of items), or as an expression like {it: uniform #A #B} (to
define these parameters as uniformly distributed in {it:]#A;#B[)}, or like
{it:gauss #M #V} (to define these parameters as the percentiles of the gaussian
distribution with mean {it:#M} and variance {it:#V}). If there is two latent
traits, the expressions are defined as {it:uniform #A1 #B1 #A2 #B2} and
{it: gauss #M1 #V1 #M2 #V2}. If this option is not defined (but the {cmd:dim}
option is), these parameters are defined among a standardized gaussian
distribution.
{p 4 8 2}{cmd:pcm}({it:matrix}) defines a matrix containing as many rows as items and
a column for each positive answer categorie. Elements of this matrix represents the
difficulty parameters of the items in a Partial Credit Model.
{p 4 8 2}{cmd:disc}({it:list_of_values}) defines the discriminating values of
the items (by default, these parameters are fixed to 1) [only for dichotomous items].
{p 4 8 2}{cmd:pmin}({it:list_of_values}) defines the minimal probability of
positive responses for each item (by default, these parameters are fixed to 0)
[only for dichotomous items].
{p 4 8 2}{cmd:pmax}({it:list_of_values}) defines the maximal probability of
positive responses for each item (by default, these parameters are fixed to 1)
[only for dichotomous items].
{p 4 8 2}{cmd:acc}({it:list_of_values}) defines the accelerating parameters
for each item (by default, these parameters are fixed to 1) [only for dichotomous items].
{p 4 8 2}{cmd:rsm1}({it:list_of_values}) and {cmd:rsm2}({it:list_of_values}) defines
the tau parameters corresponding to the difficulty parameters of the positive answer
categorie for each item in a Rating Scale Model for the first scale ({cmd:rsm1}) or
for the second scale ({cmd:rsm2}).
{p 4 8 2}{cmd:threshold} simulates the responses of each individuals directly from the latent trait.
In a dichotomous model ({cmd:disc}, {cmd:pmin}, {cmd:pmax} and {cmd:acc} options are not allowed), the response
1 if given as soon the latent trait of the individual is greater than the difficulty parameter of the item (defined with the {cmd:diff} option).
In a polytomous model , an answer is given when the latent trait of the individual is greater than the
difficulties corresponding to this answer.
{p 4 8 2}{cmd:clear} does not restore the initial dataset at the end of the
command (at least one of the {cmd:clear} and {cmd:store} options must be defined).
{p 4 8 2}{cmd:id}({it:newvarname}) defines the name of the identifiant variable (id by default).
{p 4 8 2}{cmd:store}({it:filename}) defines the file where the new dataset will
be stored (at least one of the {cmd:clear} and {cmd:store} options must be
defined).
{p 4 8 2}{cmd:replace}, associated to {cmd:store}, allows replacing the file
defined by {cmd:store}, if it already exist.
{p 4 8 2}{cmd:prefix}({it:string [string]}]) allows defining the prefix to use
for the names of the items. The {it:string} cannot contain space(s). By default,
the used prefix is "item" in the unidimensional case, and "itemA" and "itemB"
in the bidimensional case. A number follows these prefixes.
{p 4 8 2}{cmd:draw}, in the unidimensional case, this option allows drawing the
Items Characteristic Curves on a graph.
{p 4 8 2}{cmd:title} defines the title of the graphs.
{p 4 8 2}{cmd:group} defines, in the unidimensional case, two groups of patients, for
example a "treated" group (coded 1) and a "reference" group (coded 0). {cmd:group}
defines the expected rate of individuals of the first group. By default, the
affectation in the two groups is randomly provided (see the {cmd:norandom} option).
{p 4 8 2}{cmd:norandom} allows affecting between the two groups the exact rates of individuals
defined in the {cmd:group} option.
{p 4 8 2}{cmd:deltagroup} defines, in the unidimensional case, the difference between the
means of the latent trait between the two groups defined by the {cmd:group} option. This
option is disabled if the {cmd:group} option is not defined. The variance of the latent
trait is considered as equal in the two groups.
{title:Outputs}
{p 4 8 2}{cmd:r(nbobs)}: Number of simulated individuals.
{p 4 8 2}{cmd:r(mean_#)}: Empirical mean of the #th latent trait.
{p 4 8 2}{cmd:r(var_#)}: Empirical variance of the #th latent trait.
{p 4 8 2}{cmd:r(cov_12)}: Empirical covariance between the two latent traits
(if there is two simulated dimensions).
{p 4 8 2}{cmd:r(rho)}: Empirical correlation coefficient between the two latent
traits (if there is two simulated dimensions).
{title:Examples}
{p 4 8 2}{cmd: . simirt , dim(7) clear} /*simulates data by a Rasch model*/
{p 4 8 2}{cmd: . simirt , diff(gauss 0 1) dim(7) disc(.8 1.2 1.4 .6 1.4 1.0 1.1) clear}
/*simulates data by a Birnbaum model*/
{p 4 8 2}{cmd: . simirt , diff(uniform -2 3 0 1) dim(7 7) cov(2 4 1) clear}/*
simulates data with a bidimensional latent trait*/
{p 4 8 2}{cmd: . simirt , dim(7) clear group(.5) deltagroup(1)} /*simulates
data by a Rasch model, with two groups of approximate equal size of patients
and a difference between the means of the latent trait for the two groups of 1*/
{p 4 8 2}{cmd: . simirt , dim(7) clear rsm(1 .5 .2)} /*Data simulated by a RSM. Each item
has until 5 modalities*/
{title:Notes about the models}
{p 4 8 2}{bf:Rasch model}: By default, you can describe only the {cmd:diff} option.
{p 4 8 2}{bf:Birnbaum model and OPLM}: By default, the {cmd:diff} and the {cmd:disc} options must be defined.
{p 4 8 2}{bf:3-PLM}: By default, the {cmd:diff}, the {cmd:disc} and the {cmd:pmin} options must be defined.
{p 4 8 2}{bf:4-PLM}: By default, the {cmd:diff}, the {cmd:disc}, the {cmd:pmin} and the {cmd:pmax} options must be defined.
{p 4 8 2}{bf:5-PM}: The {cmd:diff}, the {cmd:disc}, the {cmd:pmin}, the {cmd:pmax} and the {cmd:acc} options must be defined.
{p 4 8 2}{bf:RSM}: The {cmd:rsm1} [and eventually the {cmd:rsm2}] option(s) must be defined. The {cmd:disc}, the {cmd:pmin}, the {cmd:pmax} and the {cmd:acc} options cannot be defined.
{p 4 8 2}{bf:PCM}: The {cmd:pcm} option must be defined. The {cmd:disc}, the {cmd:pmin}, the {cmd:pmax} and the {cmd:acc} options cannot be defined.
{title:Author}
{p 4 8 2}Jean-Benoit Hardouin, PhD, assistant professor{p_end}
{p 4 8 2}EA 4275 "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}Website {browse "http://www.anaqol.org":AnaQol}

Binary file not shown.