/** code to score the sf12 v1 **/

/**
1) check your items against sf12 v1 survey here to confirm you truly have version 1 items: 
   http://www.sf-36.org/demos/SF-12.html

2) code below was written for another purpose (sf36) so need to rename your items to match 
   the code: see rename statement below.
**/

/* INPUT TEST DATA (ID=1 is at all minimum values, ID=5 is at all maximum values) */
/* INCLUDES SOME OUT OF RANGE DATA FOR TESTING */

/* 7/25/16: update to code includes recoding items that are out-of-range to missing, */
/* item reversals, add prints, etc. */

options ls=132 ps=56 nocenter;
DATA mydata; 
INPUT id item1 item2a item2b item3a item3b item4a item4b item5 item6a item6b item6c item7;
CARDS;
1 1 1 1 1 1 1 1 1 1 1 1 1 
2 1 1 3 2 2 2 2 3 6 3 4 3 
3 1 1 . 2 2 2 2 5 5 4 3 5 
4 5 5 1 1 1 . . . . . . . 
5 5 3 3 2 2 2 2 5 6 6 6 5
6 . . . . . . . . . . . .
7 0 0 0 0 0 0 0 0 0 0 0 0
;
RUN;
TITLE "Input data"; run;
proc print; run;
*****************************************************************;
*** NEMC PHYSICAL AND MENTAL HEALTH COMPOSITE SCORES - SF-12 ****;

/** RENAME ITEMS TO CONFORM TO sf36 SURVEY **/
DATA mydata;
SET mydata(keep=id item1 item2a item2b item3a item3b item4a item4b item5 item6a item6b item6c item7 RENAME=(
item1   =I1
item2a  =I4   
item2b  =I6   
item3a  =I14  
item3b  =I15  
item4a  =I18  
item4b  =I19  
item5   =I22   
item6a  =I26  
item6b  =I27  
item6c  =I28  
item7   =I32));
RUN;  

*****************************************************************;
** CODE OUT-OF-RANGE VALUES TO MISSING;
*****************************************************************;
DATA mydata; SET mydata;

ARRAY PT5 I1 I22 I32;
DO OVER PT5;
IF PT5 NOT IN (1,2,3,4,5) THEN PT5=.;
END;

ARRAY PT2 I14 I15 I18 I19;
DO OVER PT2;
IF PT2 NOT IN (1,2) THEN PT2=.;
END;

ARRAY PT3 I4 I6;
DO OVER PT3;
IF PT3 NOT IN (1,2,3) THEN PT3=.;
END;

ARRAY PT6 I26 I27 I28;
DO OVER PT6;
IF PT6 NOT IN (1,2,3,4,5,6) THEN PT6=.;
END;
RUN;
*****************************************************************;

** put on 0-100 scale and score;
*****************************************************************;
DATA sf36v1;SET mydata;
ARRAY RFIVEPT I1 I22;
ARRAY THREEPT I4 I6;
ARRAY TWOPT   I14 I15 I18 I19;
ARRAY RSIXPT  I26 I27;
ARRAY SIXPT   I28;
ARRAY FIVEPT  I32;
*****************************************************************;
I1SF=I1; I22SF=I22;

DO OVER RFIVEPT;
 IF RFIVEPT=1 THEN RFIVEPT=100; ELSE 
 IF RFIVEPT=2 THEN RFIVEPT=75;  ELSE 
 IF RFIVEPT=3 THEN RFIVEPT=50;  ELSE 
 IF RFIVEPT=4 THEN RFIVEPT=25;  ELSE 
 IF RFIVEPT=5 THEN RFIVEPT=0;
END;

DO OVER THREEPT;
 IF THREEPT=1 THEN THREEPT=0;  ELSE 
 IF THREEPT=2 THEN THREEPT=50; ELSE 
 IF THREEPT=3 THEN THREEPT=100;
END;

DO OVER TWOPT;
 IF TWOPT=1 THEN TWOPT=0; ELSE 
 IF TWOPT=2 THEN TWOPT=100;
END;

DO OVER RSIXPT;
 IF RSIXPT=1 THEN RSIXPT=100; ELSE 
 IF RSIXPT=2 THEN RSIXPT=80;  ELSE 
 IF RSIXPT=3 THEN RSIXPT=60;  ELSE 
 IF RSIXPT=4 THEN RSIXPT=40;  ELSE 
 IF RSIXPT=5 THEN RSIXPT=20;  ELSE 
 IF RSIXPT=6 THEN RSIXPT=0;
END;

DO OVER SIXPT;
 IF SIXPT=1 THEN SIXPT=0;  ELSE 
 IF SIXPT=2 THEN SIXPT=20; ELSE 
 IF SIXPT=3 THEN SIXPT=40; ELSE 
 IF SIXPT=4 THEN SIXPT=60; ELSE 
 IF SIXPT=5 THEN SIXPT=80; ELSE 
 IF SIXPT=6 THEN SIXPT=100;
END;

DO OVER FIVEPT;
 IF FIVEPT=1 THEN FIVEPT=0;  ELSE 
 IF FIVEPT=2 THEN FIVEPT=25; ELSE 
 IF FIVEPT=3 THEN FIVEPT=50; ELSE 
 IF FIVEPT=4 THEN FIVEPT=75; ELSE 
 IF FIVEPT=5 THEN FIVEPT=100;
END;
*****************************************************************;

***************************************************;
RUN;
****************************************************;

****************************************************;
data sf36v1; set sf36v1;
*****************************************************************;

*****************************************************************;
*** B. CREATING NEMC SF-12 COMPOSITE SCORES;
*** Create dummy variables for the SF-12 items: ;
IF I1=0 THEN GH1_1=1;
 ELSE IF I1>=0 THEN GH1_1=0;
IF I1=25 THEN GH1_2=1;
 ELSE IF I1>=0 THEN GH1_2=0;
IF I1=50 THEN GH1_3=1;
 ELSE IF I1>=0 THEN GH1_3=0;
IF I1=75 THEN GH1_4=1;
 ELSE IF I1>=0 THEN GH1_4=0;
IF I4=0 THEN PF02_1=1;
 ELSE IF I4>=0 THEN PF02_1=0;
IF I4=50 THEN PF02_2=1;
 ELSE IF I4>=0 THEN PF02_2=0;
IF I6=0 THEN PF04_1=1;
 ELSE IF I6>=0 THEN PF04_1=0;
IF I6=50 THEN PF04_2=1;
 ELSE IF I6>=0 THEN PF04_2=0;
IF I14=0 THEN RP2_1=1;
 ELSE IF I14>=0 THEN RP2_1=0;
IF I15=0 THEN RP3_1=1;
 ELSE IF I15>=0 THEN RP3_1=0;
IF I18=0 THEN RE2_1=1;
 ELSE IF I18>=0 THEN RE2_1=0;
IF I19=0 THEN RE3_1=1;
 ELSE IF I19>=0 THEN RE3_1=0;
IF I22=0 THEN BP2_1=1;
 ELSE IF I22>=0 THEN BP2_1=0;
IF I22=25 THEN BP2_2=1;
 ELSE IF I22>=0 THEN BP2_2=0;
IF I22=50 THEN BP2_3=1;
 ELSE IF I22>=0 THEN BP2_3=0;
IF I22=75 THEN BP2_4=1;
 ELSE IF I22>=0 THEN BP2_4=0;
IF I26=0 THEN EM3_1=1;
 ELSE IF I26>=0 THEN EM3_1=0;
IF I26=20 THEN EM3_2=1;
 ELSE IF I26>=0 THEN EM3_2=0;
IF I26=40 THEN EM3_3=1;
 ELSE IF I26>=0 THEN EM3_3=0;
IF I26=60 THEN EM3_4=1;
 ELSE IF I26>=0 THEN EM3_4=0;
IF I26=80 THEN EM3_5=1;
 ELSE IF I26>=0 THEN EM3_5=0;
IF I27=0 THEN EN2_1=1;
 ELSE IF I27>=0 THEN EN2_1=0;
IF I27=20 THEN EN2_2=1;
 ELSE IF I27>=0 THEN EN2_2=0;
IF I27=40 THEN EN2_3=1;
 ELSE IF I27>=0 THEN EN2_3=0;
IF I27=60 THEN EN2_4=1;
 ELSE IF I27>=0 THEN EN2_4=0;
IF I27=80 THEN EN2_5=1;
 ELSE IF I27>=0 THEN EN2_5=0;
IF I28=0 THEN EM4_1=1;
 ELSE IF I28>=0 THEN EM4_1=0;
IF I28=20 THEN EM4_2=1;
 ELSE IF I28>=0 THEN EM4_2=0;
IF I28=40 THEN EM4_3=1;
 ELSE IF I28>=0 THEN EM4_3=0;
IF I28=60 THEN EM4_4=1;
 ELSE IF I28>=0 THEN EM4_4=0;
IF I28=80 THEN EM4_5=1;
 ELSE IF I28>=0 THEN EM4_5=0;
IF I32=0 THEN SF2_1=1;
 ELSE IF I32>=0 THEN SF2_1=0;
IF I32=25 THEN SF2_2=1;
 ELSE IF I32>=0 THEN SF2_2=0;
IF I32=50 THEN SF2_3=1;
 ELSE IF I32>=0 THEN SF2_3=0;
IF I32=75 THEN SF2_4=1;
 ELSE IF I32>=0 THEN SF2_4=0;
run;

data sf36v1; set sf36v1;
*** 2) Create SF-12 aggregates: *************************;

   RAWPCS12 = (PF02_1 *  -7.23216) + (PF02_2 * -3.45555) +
              (PF04_1 *  -6.24397) + (PF04_2 * -2.73557) +
              (RP2_1  *  -4.61617) + (RP3_1  * -5.51747) +
              (BP2_1  * -11.25544) + (BP2_2  * -8.38063) +
              (BP2_3  *  -6.50522) + (BP2_4  * -3.80130) +
              (GH1_1  *  -8.37399) + (GH1_2  * -5.56461) +
              (GH1_3  *  -3.02396) + (GH1_4  * -1.31872) +
              (EN2_1  *  -2.44706) + (EN2_2  * -2.02168) +
              (EN2_3  *  -1.61850) + (EN2_4  * -1.14387) +
              (EN2_5  *  -0.42251) + (SF2_1  * -0.33682) +
              (SF2_2  *  -0.94342) + (SF2_3  * -0.18043) +
              (SF2_4  *   0.11038) + (RE2_1  *  3.04365) +
              (RE3_1  *   2.32091) + (EM3_1  *  3.46638) +
              (EM3_2  *   2.90426) + (EM3_3  *  2.37241) +
              (EM3_4  *   1.36689) + (EM3_5  *  0.66514) +
              (EM4_1  *   4.61446) + (EM4_2  *  3.41593) +
              (EM4_3  *   2.34247) + (EM4_4  *  1.28044) +
              (EM4_5  *   0.41188);
   RAWMCS12 = (PF02_1 *   3.93115) + (PF02_2 *   1.86840) +
              (PF04_1 *   2.68282) + (PF04_2 *   1.43103) +
              (RP2_1  *   1.44060) + (RP3_1  *   1.66968) +
              (BP2_1  *   1.48619) + (BP2_2  *   1.76691) +
              (BP2_3  *   1.49384) + (BP2_4  *   0.90384) +
              (GH1_1  *  -1.71175) + (GH1_2  *  -0.16891) +
              (GH1_3  *   0.03482) + (GH1_4  *  -0.06064) +
              (EN2_1  *  -6.02409) + (EN2_2  *  -4.88962) +
              (EN2_3  *  -3.29805) + (EN2_4  *  -1.65178) +
              (EN2_5  *  -0.92057) + (SF2_1  *  -6.29724) +
              (SF2_2  *  -8.26066) + (SF2_3  *  -5.63286) +
              (SF2_4  *  -3.13896) + (RE2_1  *  -6.82672) +
              (RE3_1  *  -5.69921) + (EM3_1  * -10.19085) +
              (EM3_2  *  -7.92717) + (EM3_3  *  -6.31121) +
              (EM3_4  *  -4.09842) + (EM3_5  *  -1.94949) +
              (EM4_1  * -16.15395) + (EM4_2  * -10.77911) +
              (EM4_3  *  -8.09914) + (EM4_4  *  -4.59055) +
              (EM4_5  *  -1.95934);

*** 3) Transform the aggregates: ********************************;

   RPCS12 = RAWPCS12 + 56.57706 ;
   RMCS12 = RAWMCS12 + 60.75781 ;

   label rpcs12="NEMC physical health T-score - SF12";
   label rmcs12="NEMC mental health T-score - SF12";
run;

*** 4) descriptives on the scores.. ;

TITLE "Results"; run;
proc print data=sf36v1 uniform;
var id 

RAWPCS12 RAWMCS12
RPCS12 RMCS12;
run;

proc means data=sf36v1 maxdec=2;
var 
RAWPCS12 RAWMCS12
RPCS12 RMCS12;
run;
*****************************************************************;
*****************************************************************;