*! version 1.0.2 September 2011 M. Daigl AO Clinical Investigation and Documentation *! Domain : Data analysis Description : Scoring algorithm for SF36 version 2 ************************************************************************************************* * Terms and Conditions for Using the 36-Item Short Form Health Survey apply * In order to use the SF-36 Health Survey and scoring algorithms you must register at: * http://www.qualitymetric.com/DefaultPermissions/RequestInformation/tabid/233/Default.aspx * Every effort is made to test code as thoroughly as possible but user must accept * responsibility for use ************************************************************************************************* version 10 capture program drop sf36v2 program define sf36v2 syntax [if] [in] [, ACute REF(string asis) FSC(integer 1990) SUFfix(string asis) Details] marksample touse set varabbrev off /*Display which version of SF36 forms is used */ if "`acute'"== "" { display in yellow "SF36 version 2 is beeing calculated using data from a 4 week recall form" } else if "`acute'" ~= "" { display in yellow "SF36 version 2 is beeing calculated using data from a 1 week recall form" } ************************************************************************************************* * 1. Define Reference Population means and sd ************************************************************************************************* if "`ref'" ~="" { tokenize `ref' local ref_pop = "`1'" local ref_y = "`2'" } if "`ref_pop'"=="" { local ref_pop="US" } else if "`ref_pop'"~="" & "`ref_pop'"~="JP" & "`ref_pop'"~="US" { display in red "Reference population must be one of the following: US, JP" exit 198 } if "`ref_y'"=="" { /*use defaults if not defined*/ if "`ref_pop'"=="US" { local ref_y="1998" } else if "`ref_pop'"=="JP" { local ref_y="2002" } } else if "`ref_y'"~="" { if "`ref_pop'"=="US" & `ref_y'~=1998 { display in red "Currently supported US norms: 1998" exit 198 } else if "`ref_pop'"=="JP" & `ref_y'~=2002 { display in red "Currently supported JP norms: 2002" exit 198 } } if "`acute'"=="" { if "`ref_pop'"=="US" & "`ref_y'"=="1998" { local ref_m="83.29094 82.50964 71.32527 70.84570 58.31411 84.30250 87.39733 74.98685" local ref_sd="23.75883 25.52028 23.66224 20.97821 20.01923 22.91921 21.43778 17.75604" } else if "`ref_pop'"=="JP" & "`ref_y'"=="2002" { local ref_m="87.70901 88.55583 74.18785 64.04815 62.00366 86.51170 87.13488 71.66899" local ref_sd="14.19995 18.32648 22.59283 18.49784 20.31911 19.00734 19.60730 18.81024" } } else if "`acute'"~="" { if "`ref_pop'"=="US" & "`ref_y'"=="1998" { local ref_m="82.62455 82.65109 73.86999 70.78372 58.41968 85.11568 87.50009 75.76034" local ref_sd="24.43176 26.19282 24.00884 21.28902 20.87823 23.24464 22.01216 18.04746" } else if "`ref'"=="JP" & "`ref_y'"="2002" { display in red "Acute Form not supported for JP population" exit 198 } } ************************************************************************************************* * 2. Define reference Factor Score Coefficients ************************************************************************************************* if ("`ref_pop'"=="US" | "`ref_pop'"=="JP") & "`fsc'"=="1990" { local fsc_PCS="0.42402 0.35119 0.31754 0.24954 0.02877 -0.00753 -0.19206 -0.22069" local fsc_MCS="-0.22999 -0.12329 -0.09731 -0.01571 0.23534 0.26876 0.43407 0.48581" } else if "`ref_pop'"=="JP" & "`fsc'"=="1995" { local fsc_PCS="0.42796 0.49529 0.13995 -0.00866 -0.19126 0.06965 0.33214 -0.24931" local fsc_MCS="-0.18362 -0.21633 0.10532 0.24000 0.42270 0.17259 -0.07121 0.45970" } ************************************************************************************************* * 3. Prepare variables for calculation ************************************************************************************************* qui { tempvar aggPHYS aggMENT foreach x in PF RP BP GH VT SF RE MH HT { tempvar m`x' c`x' r`x' } foreach x in PF01 PF02 PF03 PF04 PF05 PF06 PF07 PF08 PF09 PF10 RP01 RP02 RP03 RP04 /// BP01 BP02 GH01 GH02 GH03 GH04 GH05 VT01 VT02 VT03 VT04 SF01 SF02 /// RE01 RE02 RE03 MH01 MH02 MH03 MH04 MH05 HT { tempvar p`x' x`x' gen `p`x''=`x'`suffix' if `touse' gen `x`x''=1 if `x'`suffix'~=. } } local dimensions="PF RP BP GH VT SF RE MH" ************************************************************************************************* * 4. Verify occurence of out-of-range item values ************************************************************************************************* tempvar alarm1 alarm2 alarm3 qui gen `alarm1'= . foreach item in PF01 PF02 PF03 PF04 PF05 PF06 PF07 PF08 PF09 PF10 { qui replace `alarm1' = 1 if `p`item'' ~=. & ( `p`item'' <1 | `p`item'' >3) list `item'`suffix' if `p`item'' ~=. & ( `p`item'' <1 | `p`item'' >3) } qui gen `alarm2'=. foreach item in RP01 RP02 RP03 RP04 BP02 /// GH01 GH02 GH03 GH04 GH05 VT01 VT02 /// VT03 VT04 SF01 SF02 RE01 RE02 RE03 /// MH01 MH02 MH03 MH04 MH05 HT { qui replace `alarm2'=1 if `p`item'' ~=. & ( `p`item'' <1 | `p`item'' >5) list `item'`suffix' if `p`item'' ~=. & ( `p`item'' <1 | `p`item'' >5) } qui gen `alarm3'=. qui replace `alarm3'=1 if `pBP01'~=. & (`pBP01' < 1 | `pBP01' >6 ) list BP01`suffix' if `pBP01'~=. & (`pBP01' < 1 | `pBP01' >6 ) qui summ `alarm1' local r1=`r(N)' qui summ `alarm2' local r2=`r(N)' qui summ `alarm3' local r3=`r(N)' if `r1'~=0 | `r2'~=0 | `r3'~=0 { display in red "Out of range values found as described above" exit } ************************************************************************************************* * 5. Reverse score and/or recalibrate scores for 10 items (Precoded item value to final item value) ************************************************************************************************* qui { foreach x in PF01 PF02 PF03 PF04 PF05 PF06 PF07 PF08 PF09 PF10 RP01 RP02 RP03 RP04 { tempvar f`x' gen `f`x''=`p`x'' /* PF and RP scale do not require recoding of items*/ } tempvar fBP01 recode `pBP01' (1=6) (2=5.4) (3=4.2) (4=3.1) (5=2.2) (6=1.0), gen(`fBP01') tempvar fBP02 gen `fBP02' = 6 if (`xBP01'~=. & `xBP02'~=. & `pBP02'==1 & `pBP01'==1) replace `fBP02' = 5 if (`xBP01'~=. & `xBP02'~=. & `pBP02'==1 & `pBP01'>=2 & `pBP01'<=6) replace `fBP02' = 4 if (`xBP01'~=. & `xBP02'~=. & `pBP02'==2 & `pBP01'>=1 & `pBP01'<=6) replace `fBP02' = 3 if (`xBP01'~=. & `xBP02'~=. & `pBP02'==3 & `pBP01'>=1 & `pBP01'<=6) replace `fBP02' = 2 if (`xBP01'~=. & `xBP02'~=. & `pBP02'==4 & `pBP01'>=1 & `pBP01'<=6) replace `fBP02' = 1 if (`xBP01'~=. & `xBP02'~=. & `pBP02'==5 & `pBP01'>=1 & `pBP01'<=6) replace `fBP02'=`pBP02' if `xBP01'==. recode `fBP02' (1=6.0) (2=4.75) (3=3.5) (4=2.25) (5=1.0) if `xBP01'==. tempvar fGH01 recode `pGH01' (1=5.0) (2=4.4) (3=3.4) (4=2.0) (5=1.0), gen(`fGH01') foreach x in GH02 GH04 VT03 VT04 SF02 RE01 RE02 RE03 MH01 MH02 MH04 HT { tempvar f`x' gen `f`x''=`p`x'' } foreach x in GH03 GH05 SF01 VT01 VT02 MH03 MH05 { tempvar f`x' recode `p`x'' (1=5) (2=4) (4=2) (5=1), gen(`f`x'') } } ************************************************************************************************* * 6. Recode missing item responses with mean substitution ************************************************************************************************ qui { * create means egen `mPF'=rowmean(`fPF01' `fPF02' `fPF03' `fPF04' `fPF05' `fPF06' `fPF07' `fPF08' `fPF09' `fPF10') egen `cPF'=rownonmiss(`fPF01' `fPF02' `fPF03' `fPF04' `fPF05' `fPF06' `fPF07' `fPF08' `fPF09' `fPF10') egen `mRP'=rowmean(`fRP01' `fRP02' `fRP03' `fRP04') egen `cRP'=rownonmiss(`fRP01' `fRP02' `fRP03' `fRP04') egen `mBP'=rowmean(`fBP01' `fBP02') egen `cBP'=rownonmiss(`fBP01' `fBP02') egen `mGH'=rowmean(`fGH01' `fGH02' `fGH03' `fGH04' `fGH05') egen `cGH'=rownonmiss(`fGH01' `fGH02' `fGH03' `fGH04' `fGH05') egen `mVT'=rowmean(`fVT01' `fVT02' `fVT03' `fVT04') egen `cVT'=rownonmiss(`fVT01' `fVT02' `fVT03' `fVT04') egen `mSF'=rowmean(`fSF01' `fSF02') egen `cSF'=rownonmiss(`fSF01' `fSF02') egen `mRE'=rowmean(`fRE01' `fRE02' `fRE03') egen `cRE'=rownonmiss(`fRE01' `fRE02' `fRE03') egen `mMH'=rowmean(`fMH01' `fMH02' `fMH03' `fMH04' `fMH05') egen `cMH'=rownonmiss(`fMH01' `fMH02' `fMH03' `fMH04' `fMH05') * mean imputation foreach x in fPF01 fPF02 fPF03 fPF04 fPF05 fPF06 fPF07 fPF08 fPF09 fPF10 { replace ``x''=`mPF' if ``x''==. & `cPF'>=5 } foreach x in fRP01 fRP02 fRP03 fRP04 { replace ``x''=`mRP' if ``x''==. & `cRP'>=2 } foreach x in fBP01 fBP02 { replace ``x''=`mBP' if ``x''==. & `cBP'>=1 } foreach x in fGH01 fGH02 fGH03 fGH04 fGH05 { replace ``x''=`mGH' if ``x''==. & `cGH'>=3 } foreach x in fVT01 fVT02 fVT03 fVT04 { replace ``x''=`mVT' if ``x''==. & `cVT'>=2 } foreach x in fSF01 fSF02 { replace ``x''=`mSF' if ``x''==. & `cSF'>=1 } foreach x in fRE01 fRE02 fRE03 { replace ``x''=`mRE' if ``x''==. & `cRE'>=2 } foreach x in fMH01 fMH02 fMH03 fMH04 fMH05 { replace ``x''=`mMH' if ``x''==. & `cMH'>=3 } } ************************************************************************************************* * 7. Compute Raw Scale Scores ************************************************************************************************* qui { gen `rPF' = `fPF01' + `fPF02' + `fPF03' + `fPF04' + `fPF05' + `fPF06' + `fPF07' + `fPF08' + `fPF09' + `fPF10' gen `rRP' = `fRP01' + `fRP02' + `fRP03' + `fRP04' gen `rBP' = `fBP01' + `fBP02' gen `rGH' = `fGH01' + `fGH02' + `fGH03' + `fGH04' + `fGH05' gen `rVT' = `fVT01' + `fVT02' + `fVT03' + `fVT04' gen `rSF' = `fSF01' + `fSF02' gen `rRE' = `fRE01' + `fRE02' + `fRE03' gen `rMH' = `fMH01' + `fMH02' + `fMH03' + `fMH04' + `fMH05' } ************************************************************************************************* * 8. Tranform raw scale scores to 0-100 scale ************************************************************************************************* qui { gen PF`suffix' = ((`rPF'-10)/20)*100 gen RP`suffix' = ((`rRP'-4)/16)*100 gen BP`suffix' = ((`rBP'-2)/10)*100 gen GH`suffix' = ((`rGH'-5)/20)*100 gen VT`suffix' = ((`rVT'-4)/16)*100 gen SF`suffix' = ((`rSF'-2)/8)*100 gen RE`suffix' = ((`rRE'-3)/12)*100 gen MH`suffix' = ((`rMH'-5)/20)*100 foreach x in PF RP BP GH VT SF RE MH { if "`suffix'" == "" { label var `x' "Transformed `x' Score" } else if "`suffix'" ~= "" { label var `x'`suffix' "Transformed `x' Score (`suffix')" } } } display in gr "0-100 scores generated (PF`suffix'-MH`suffix')" ************************************************************************************************* * 9. Transform 0-100 score to norm-based scores ************************************************************************************************* noi { foreach i of numlist 1/8 { local mean: word `i' of `ref_m' local sd: word `i' of `ref_sd' local dim: word `i' of `dimensions' tempvar z`dim' qui gen `z`dim''=(`dim'`suffix'-`mean')/`sd' /*z-score standardization of SF-36v2 Scales*/ qui gen `dim'_NBS`suffix'=50+(`z`dim''*10) /*Norm-based tranformation of SF-26v2 z-scores*/ } foreach x in PF RP BP GH VT SF RE MH { if "`suffix'" == "" { label var `x'_NBS "Norm-Based `x' Score" } else if "`suffix'" ~= "" { label var `x'_NBS`suffix' "Norm-Based `x' Score (`suffix')" } } } display in gr "Norm-based scores generated (PF_NBS`suffix'-MH_NBS`suffix')" ************************************************************************************************* * 10. Scoring SF-36v2 Physical and Mental Summary Measures ************************************************************************************************* qui { foreach i of numlist 1/8 { local dim: word `i' of `dimensions' local pfsc`dim': word `i' of `fsc_PCS' local mfsc`dim': word `i' of `fsc_MCS' } #delimit ; gen `aggPHYS'=(`zPF'*`pfscPF') + (`zRP'*`pfscRP') + (`zBP'*`pfscBP') + (`zGH'*`pfscGH') + (`zVT'*`pfscVT') + (`zSF'*`pfscSF') + (`zRE'*`pfscRE') + (`zMH'*`pfscMH') ; gen `aggMENT'=(`zPF'*`mfscPF') + (`zRP'*`mfscRP') + (`zBP'*`mfscBP') + (`zGH'*`mfscGH') + (`zVT'*`mfscVT') + (`zSF'*`mfscSF') + (`zRE'*`mfscRE') + (`zMH'*`mfscMH') ; #delimit cr gen PCS`suffix' = 50 + (`aggPHYS' * 10) gen MCS`suffix' = 50 + (`aggMENT' * 10) if "`suffix'"=="" { label var PCS`suffix' "Physical Component Score" label var MCS`suffix' "Mental Component Score" } else if "`suffix'"~="" { label var PCS`suffix' "Physical Component Score (`suffix')" label var MCS`suffix' "Mental Component Score (`suffix')" } } display in gr "Physical and Mental Component Summary generated (PCS`suffix',MCS`suffix')" if "`details'"~="" { display "Norms and Coefficients used for the calculation:" display " +----------------------------------------------------+" display " | ---Norms--- -Factor Score Coef- |" display " | (`ref_pop' `ref_y') (`fsc') |" display " | Dimension mean sd PCS MCS |" foreach i of numlist 1/8 { local dim: word `i' of `dimensions' local mean: word `i' of `ref_m' local sd: word `i' of `ref_sd' local pfsc: word `i' of `fsc_PCS' local mfsc: word `i' of `fsc_MCS' display " | `dim' `mean' `sd' " %8s "`pfsc'" " "%8s "`mfsc'" " |" } display " +----------------------------------------------------+" } set varabbrev on end