You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
430 lines
16 KiB
Plaintext
430 lines
16 KiB
Plaintext
7 months ago
|
*! Version 5.2 24September2019
|
||
|
*!Jean-Benoit Hardouin
|
||
|
*
|
||
|
************************************************************************************************************
|
||
|
* Traces: Traces of items
|
||
|
*
|
||
|
* Historic:
|
||
|
* Version 1 (2003-06-29) [Jean-Benoit Hardouin]
|
||
|
* Version 2 (2003-07-04 [Jean-Benoit Hardouin]
|
||
|
* version 3 (2003-07-09) [Jean-Benoit Hardouin]
|
||
|
* Version 3.1 (2005-06-07) [Jean-Benoit Hardouin] /*small modifications*/
|
||
|
* Version 3.2: May 27, 2007 [Jean-Benoit Hardouin] /*onlyone option*/
|
||
|
* Version 3.3: October 16, 2012 [Jean-Benoit Hardouin] /*minor modifications*/
|
||
|
* Version 4: January 22, 2015 [Jean-Benoit Hardouin] /*ICC*/
|
||
|
* Version 5: March 5, 2016 [Jean-Benoit Hardouin] /*numerical items*/
|
||
|
* Version 5.1: July 13, 2019 [Jean-Benoit Hardouin] /*Bugs Corrections*/
|
||
|
* Version 5.2: September 24, 2019 [Jean-Benoit Hardouin] /*Bugs Corrections*/
|
||
|
*
|
||
|
* 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 2003, 2005, 2007, 2012, 2015, 2016, 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 traces, rclass
|
||
|
version 8.0
|
||
|
syntax varlist(numeric min=2) [, /*COMPare(varlist min=2 max=2*/ ICC noGraph Score Test Restscore Logistic CI CUMulative REPFiles(string) DIRSave(string) FILESave SCOREFiles(string) RESTSCOREFiles(string) LOGISTICFile(string) ICCFile(string) noDraw noDRAWComb REPlace ONLYone(string) THResholds(string) Black]
|
||
|
|
||
|
local nbitems : word count `varlist'
|
||
|
tokenize `varlist'
|
||
|
|
||
|
if "`onlyone'"!=""&"`drawcomb'"!="" {
|
||
|
local drawcomb
|
||
|
}
|
||
|
|
||
|
if "`repfiles'"!=""&"`dirsave'"=="" {
|
||
|
local dirsave `repfile'
|
||
|
}
|
||
|
if "`filesave'"=="" {
|
||
|
local saving
|
||
|
}
|
||
|
else {
|
||
|
if "`dirsave'"=="" {
|
||
|
local dirsave `c(pwd)'
|
||
|
}
|
||
|
if "`scorefiles'"=="" {
|
||
|
local scorefiles score
|
||
|
}
|
||
|
if "`restscorefiles'"=="" {
|
||
|
local restscorefiles restscore
|
||
|
}
|
||
|
if "`logicticfile'"=="" {
|
||
|
local logisticfile logistic
|
||
|
}
|
||
|
if "`iccfiles'"=="" {
|
||
|
local iccfiles icc
|
||
|
}
|
||
|
}
|
||
|
|
||
|
tempvar varscore
|
||
|
qui gen `varscore'=0
|
||
|
label variable `varscore' "Total score"
|
||
|
local scoremax=0
|
||
|
local flag=0
|
||
|
|
||
|
if "`score'"==""&"`restscore'"==""&&"`logistic'"=="" {
|
||
|
local score="score"
|
||
|
}
|
||
|
|
||
|
local modamax=-999
|
||
|
local modamin=999
|
||
|
forvalues i=1/`nbitems' {
|
||
|
qui replace `varscore'=`varscore'+``i''
|
||
|
qui su ``i''
|
||
|
local modamax`i'=r(max)
|
||
|
local modamin`i'=r(min)
|
||
|
if r(min)!=0 {
|
||
|
local flag=1
|
||
|
}
|
||
|
local scoremax=`scoremax'+`modamax`i''
|
||
|
if `modamax`i''!=1 {
|
||
|
local flagbin=0
|
||
|
}
|
||
|
if `modamax`i''>`modamax' {
|
||
|
local modamax=`modamax`i''
|
||
|
}
|
||
|
if `modamin`i''<`modamin' {
|
||
|
local modamin=`modamin`i''
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
if `flag'==1 {
|
||
|
di as error "The lower modality of the item must be 0"
|
||
|
exit
|
||
|
}
|
||
|
*/
|
||
|
if "`flagbin'"!=""&"`logistic'"!="" {
|
||
|
di as error "The logistic option is not possible with polytomous items"
|
||
|
exit
|
||
|
}
|
||
|
|
||
|
qui su `varscore'
|
||
|
local maxscore=r(max)
|
||
|
local minscore=r(min)
|
||
|
|
||
|
forvalues i=`minscore'/`maxscore' {
|
||
|
qui count if `varscore'>`=`i'-0.5'&`varscore'<=`=`i'+0.5'
|
||
|
local nscore`i'=r(N)
|
||
|
}
|
||
|
|
||
|
|
||
|
global score
|
||
|
global restscore
|
||
|
global logistic
|
||
|
qui count
|
||
|
local N=r(N)
|
||
|
if `c(matsize)'<`N'&"`saveicc'"!="" {
|
||
|
set matsize `N'
|
||
|
}
|
||
|
|
||
|
|
||
|
if "`score'"!="" {
|
||
|
if "`thresholds'"!="" {
|
||
|
* set trace on
|
||
|
local nbth:word count `thresholds'
|
||
|
forvalues t=1/`nbth' {
|
||
|
local th`t':word `t' of `thresholds'
|
||
|
}
|
||
|
tempname label
|
||
|
local recode min/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1'
|
||
|
qui label define `label' 1 "min/`th1'",add
|
||
|
qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add
|
||
|
forvalues j=2/`nbth' {
|
||
|
local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j'
|
||
|
qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add
|
||
|
}
|
||
|
tempname varscore2
|
||
|
qui gen `varscore2'=`varscore'
|
||
|
qui recode `varscore' `recode'
|
||
|
qui label values `varscore' `label'
|
||
|
local nbgroups=`nbth'+1
|
||
|
local minimum=1
|
||
|
}
|
||
|
else {
|
||
|
local nbgroups=`maxscore'
|
||
|
local minimum=0
|
||
|
}
|
||
|
local listicc
|
||
|
local widthicc
|
||
|
|
||
|
forvalues i=1/`nbitems' {
|
||
|
local y`i'
|
||
|
tempvar icc``i''
|
||
|
gen `icc``i'''=0
|
||
|
label variable `icc``i''' "``i''"
|
||
|
local listicc `listicc' `icc``i'''
|
||
|
local l=0
|
||
|
*set trace on
|
||
|
forvalues k=`=`modamin`i''+1'/`modamax`i'' {
|
||
|
tempvar propscore`i'`k' tmp propscoreicc`i'`k' tmp2
|
||
|
if "`cumulative'"!="" {
|
||
|
qui gen `tmp'=``i''>=`k'&``i''!=.
|
||
|
bysort `varscore' : egen `propscore`i'`k''=mean(`tmp')
|
||
|
label variable `propscore`i'`k'' "Item ``i''>=`k'"
|
||
|
}
|
||
|
else {
|
||
|
qui gen `tmp'=``i''==`k'&``i''!=.
|
||
|
bysort `varscore' : egen `propscore`i'`k''=mean(`tmp')
|
||
|
label variable `propscore`i'`k'' "Item ``i''=`k'"
|
||
|
}
|
||
|
if "`icc'"!="" {
|
||
|
qui gen `tmp2'=``i''==`k'&``i''!=.
|
||
|
bysort `varscore' : egen `propscoreicc`i'`k''=mean(`tmp2')
|
||
|
qui replace `icc``i'''=`icc``i'''+`k'*`propscoreicc`i'`k''
|
||
|
}
|
||
|
*di "replace icc``i''=icc``i''+`k'*`propscore`i'`k''"
|
||
|
local y`i'="`y`i'' `propscore`i'`k''"
|
||
|
local style="solid"
|
||
|
local color="black"
|
||
|
local width="medthick"
|
||
|
if `modamax`i''==1&"`ci'"!="" {
|
||
|
tempvar icscoreminus icscoreplus
|
||
|
forvalues m=1/`maxscore' {
|
||
|
qui count if `varscore'==`m'
|
||
|
local nscore`m'=r(N)
|
||
|
}
|
||
|
qui gen `icscoreminus'=`propscore`i'1'-1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1')
|
||
|
qui gen `icscoreplus'=`propscore`i'1'+1.96*sqrt(`propscore`i'1'*(1-`propscore`i'1')/`nscore1')
|
||
|
label variable `icscoreminus' "Lower 95% confidence interval"
|
||
|
label variable `icscoreplus' "Upper 95% confidence interval"
|
||
|
local y`i'="`icscoreminus' `icscoreplus' `propscore`i'1'"
|
||
|
local style="dash dash solid"
|
||
|
local color="red red black"
|
||
|
local width="thin thin medthick"
|
||
|
}
|
||
|
if `modamax`i''==1&"`test'"!="" {
|
||
|
qui regress `propscore`i'1' `varscore'
|
||
|
local p=Fden(e(df_m),e(df_r),e(F))
|
||
|
if `p'<0.0001 {
|
||
|
local note="Test: slope=0, p<0.0001"
|
||
|
}
|
||
|
else {
|
||
|
local p=substr("`p'",1,6)
|
||
|
local note="Test: slope=0, p=`p'"
|
||
|
}
|
||
|
}
|
||
|
local ++l
|
||
|
}
|
||
|
*set trace on
|
||
|
if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`graph'"=="" {
|
||
|
if "`filesave'"!="" {
|
||
|
local saving "saving(`dirsave'//`scorefiles'_``i'',replace)"
|
||
|
}
|
||
|
qui graph twoway (line `y`i'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , note("`note'") ylabel(0(.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title("Trace of the item ``i'' as a function of the score") ytitle("Rate of positive response") `draw' `saving'
|
||
|
}
|
||
|
if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`icc'"!=""&"`graph'"==""{
|
||
|
if "`filesave'"!="" {
|
||
|
local saving "saving(`dirsave'//`iccfiles'_``i'',replace)"
|
||
|
}
|
||
|
local widthicc `widthicc' medthick
|
||
|
qui graph twoway (line `icc``i''' `varscore', /*clpattern(`style') clcolor(`color')*/ clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax`i'') xlabel(`minimum'(1)`nbgroups',valuelabel) name(icc`i',replace) title("Approximate ICC of the item ``i'' as a function of the score") ytitle("Mean response") `draw' `saving'
|
||
|
}
|
||
|
/*
|
||
|
global score "$score score`i'"
|
||
|
if "`scorefiles'"!="" {
|
||
|
graph save score`i' `dirsave'\\`scorefiles'``i'' ,`replace'
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
if "`saveicc'"!="" {
|
||
|
local listicc `listicc' `varscore'
|
||
|
tempname matscore
|
||
|
mkmat `listicc',matrix(`matscore')
|
||
|
}
|
||
|
if "`thresholds'"!="" {
|
||
|
qui replace `varscore'=`varscore2'
|
||
|
}
|
||
|
if "`onlyone'"==""&"`icc'"!=""&"`graph'"=="" {
|
||
|
if "`filesave'"!="" {
|
||
|
local saving "saving(`dirsave'//`iccfiles',replace)"
|
||
|
}
|
||
|
qui graph twoway (line `listicc' `varscore', /*clpattern(`style') clcolor(`color')*/ clwidth(`widthicc')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax`i'') xlabel(`minimum'(1)`nbgroups',valuelabel) name(icc,replace) title("Approximate ICC of the items as a function of the score") ytitle("Mean response") `draw' `saving'
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
if "`compare'"!=""&"`graph'"=="" {
|
||
|
local tmp1 : word 1 of `compare'
|
||
|
local tmp2 : word 2 of `compare'
|
||
|
di "compare `compare' tmp1 `tmp1' tmp2 `tmp2'"
|
||
|
label variable `icc`tmp1'' `tmp1'
|
||
|
label variable `icc`tmp2'' `tmp2'
|
||
|
di "qui graph twoway (line `icc`tmp1'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) (line `icc`tmp2'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax') xlabel(`minimum'(1)`nbgroups',valuelabel) name(score`i',replace) title(Comparison of the ICC of the items `tmp1' and `tmp2') `draw' /*areastyle(none)*/"
|
||
|
qui graph twoway (line `icc`tmp1'' `varscore', clpattern(`style') clcolor(blue red) clwidth(`width')) (line `icc`tmp2'' `varscore', clpattern(`style') clcolor(`color') clwidth(`width')) if `varscore'!=0&`varscore'!=`maxscore' , ylabel(0(.5)`modamax') xlabel(`minimum'(1)`nbgroups',valuelabel) /*name(score`i',replace)*/ title("Comparison of the ICC of the items `tmp1' and `tmp2'") ytitle("Mean response") /*areastyle(none)*/
|
||
|
}
|
||
|
*/
|
||
|
*set trace on
|
||
|
if "`restscore'"!="" {
|
||
|
forvalues i=1/`nbitems' {
|
||
|
local y`i'
|
||
|
tempvar restscore`i'
|
||
|
qui gen `restscore`i''=`varscore'-``i''
|
||
|
label variable `restscore`i'' "Rest score with respect to the item ``i''"
|
||
|
if "`thresholds'"!="" {
|
||
|
* set trace on
|
||
|
local nbth:word count `thresholds'
|
||
|
forvalues t=1/`nbth' {
|
||
|
local th`t':word `t' of `thresholds'
|
||
|
}
|
||
|
tempname label
|
||
|
local recode 0/`th1'=1 `=`th`nbth''+1'/max=`=`nbth'+1'
|
||
|
qui label define `label' 1 "min/`th1'",add
|
||
|
qui label define `label' `=`nbth'+1' "`=`th`nbth''+1'/max",add
|
||
|
forvalues j=2/`nbth' {
|
||
|
local recode `recode' `=`th`=`j'-1''+1'/`th`j''=`j'
|
||
|
qui label define `label' `j' "`=`th`=`j'-1''+1'/`th`j''",add
|
||
|
}
|
||
|
|
||
|
*di "recode `restscore`i'' `recode'"
|
||
|
qui recode `restscore`i'' `recode'
|
||
|
qui label values `restscore`i'' `label'
|
||
|
local nbgroups=`nbth'+1
|
||
|
local minimum=1
|
||
|
}
|
||
|
else {
|
||
|
local nbgroups=`maxscore'
|
||
|
local minimum=0
|
||
|
}
|
||
|
|
||
|
forvalues k=1/`modamax`i'' {
|
||
|
tempvar rtmp proprestscore`i'`k'
|
||
|
if "`cumulative'"!="" {
|
||
|
qui gen `rtmp'=``i''>=`k'&``i''!=.
|
||
|
bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp')
|
||
|
label variable `proprestscore`i'`k'' "Item ``i''>=`k'"
|
||
|
}
|
||
|
else {
|
||
|
qui gen `rtmp'=``i''==`k'&``i''!=.
|
||
|
bysort `restscore`i'': egen `proprestscore`i'`k''=mean(`rtmp')
|
||
|
label variable `proprestscore`i'`k'' "Item ``i''=`k'"
|
||
|
}
|
||
|
local y`i'="`y`i'' `proprestscore`i'`k''"
|
||
|
local style="solid"
|
||
|
local color="black"
|
||
|
local width="medthick"
|
||
|
if `modamax`i''==1&"`ci'"!="" {
|
||
|
tempvar icrestscoreminus icrestscoreplus
|
||
|
qui su `restscore`i''
|
||
|
local maxrestscore=r(max)
|
||
|
forvalues l=1/`maxrestscore' {
|
||
|
qui count if `restscore`i''==`l'
|
||
|
local nrestscore`i'=r(N)
|
||
|
}
|
||
|
qui gen `icrestscoreminus'=`proprestscore`i'1'-1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'')
|
||
|
qui gen `icrestscoreplus'=`proprestscore`i'1'+1.96*sqrt(`proprestscore`i'1'*(1-`proprestscore`i'1')/`nrestscore`i'')
|
||
|
label variable `icrestscoreminus' "Lower 95% confidence interval"
|
||
|
label variable `icrestscoreplus' "Upper 95% confidence interval"
|
||
|
local y`i'="`icrestscoreminus' `icrestscoreplus' `proprestscore`i'1'"
|
||
|
local style="dash dash solid"
|
||
|
local color="red red black"
|
||
|
local width="thin thin medthick"
|
||
|
}
|
||
|
if `modamax`i''==1&"`test'"!="" {
|
||
|
qui regress `proprestscore`i'1' `varscore'
|
||
|
local p=Fden(e(df_m),e(df_r),e(F))
|
||
|
if `p'<0.0001 {
|
||
|
local note="Test: slope=0, p<0.0001"
|
||
|
}
|
||
|
else {
|
||
|
local p=substr("`p'",1,6)
|
||
|
local note="Test: slope=0, p=`p'"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
local restscoremax=`scoremax'-`modamax`i''
|
||
|
if ("``i''"=="`onlyone'"|"`onlyone'"=="")&"`graph'"=="" {
|
||
|
if "`filesave'"!="" {
|
||
|
local saving "saving(`dirsave'//`restscorefiles'_``i'',replace)"
|
||
|
}
|
||
|
qui graph twoway (line `y`i'' `restscore`i'', clpattern(`style') clcolor(`color') clwidth(`width')), note("`note'") ylabel(0(0.25)1) xlabel(`minimum'(1)`nbgroups',valuelabel) name(restscore`i',replace) title("Trace of the item ``i'' as a function of the restscore") ytitle("Rate of positive response") `draw' `saving'
|
||
|
}
|
||
|
/*
|
||
|
global restscore "$restscore restscore`i'"
|
||
|
if "`restscorefiles'"!="" {
|
||
|
graph save restscore`i' `dirsave'\\`restscorefiles'``i'' ,`replace'
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
}
|
||
|
if "`logistic'"!="" {
|
||
|
forvalues i=1/`nbitems' {
|
||
|
qui logistic ``i'' `varscore'
|
||
|
tempname coef
|
||
|
matrix `coef'=e(b)
|
||
|
local pente`i'=`coef'[1,1]
|
||
|
local intercept`i'=`coef'[1,2]
|
||
|
tempvar logit`i'
|
||
|
qui gen `logit`i''=exp(`intercept`i''+`pente`i''*`varscore')/(1+exp(`intercept`i''+`pente`i''*`varscore'))
|
||
|
label variable `logit`i'' "Item ``i''"
|
||
|
sort `varscore'
|
||
|
global logistic "$logistic `logit`i''"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if "`score'"!=""&"`onlyone'"==""&"`graph'"==""&"`drawcomb'"=="" {
|
||
|
if "`filesave'"!="" {
|
||
|
local saving "saving(`dirsave'//`scorefiles',replace)"
|
||
|
}
|
||
|
local score
|
||
|
local restscoreg
|
||
|
forvalues i=1/`nbitems'{
|
||
|
local score `score' score`i'
|
||
|
local restscoreg `restscoreg' restscore`i'
|
||
|
}
|
||
|
|
||
|
qui graph combine `score', title("Trace of the items as a function of the score") name(score,replace) `draw' `saving'
|
||
|
/*
|
||
|
if "`scorefiles'"!="" {
|
||
|
graph save score `dirsave'\\`scorefiles' ,`replace'
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
if "`restscore'"!=""&"`onlyone'"==""&"`graph'"==""&"`drawcomb'"=="" {
|
||
|
if "`filesave'"!="" {
|
||
|
local saving "saving(`dirsave'//`restscorefiles',replace)"
|
||
|
}
|
||
|
qui graph combine `restscoreg' , title("Trace of the items as a function of the restscores") name(restscore,replace) `draw' `saving'
|
||
|
/*
|
||
|
if "`restscorefiles'"!="" {
|
||
|
graph save restscore `dirsave'\\`restscorefiles' ,`replace'
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
if "`logistic'"!=""&"`onlyone'"==""&"`graph'"=="" {
|
||
|
if "`filesave'"!="" {
|
||
|
local saving "saving(`dirsave'//`logisticfile',replace)"
|
||
|
}
|
||
|
qui graph twoway (line $logistic `varscore'), ylabel(0(0.25)1) xlabel(0(1)`nbitems') title("Logistic traces") ytitle("") name(logistic,replace) `draw'
|
||
|
/*
|
||
|
if "`logisticfile'"!="" {
|
||
|
graph save logistic `dirsave'\\`logisticfile' ,`replace'
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
if "`saveicc'"!="" {
|
||
|
return matrix matscore=`matscore'
|
||
|
}
|
||
|
end
|
||
|
|
||
|
|