options ls=78 ps=56 nocenter;

 /*  SF-12 v1 US version */

/*
Weighting of domain scores from Brazier JE, Roberts JR, (2004) 
The estimation of a preference-based index from the SF-12. 
Medical Care, 42: 851-859. 

Karen Spritzer for Ron Hays 5/2012.
Based on Brazier's sf6d_sf12v1_US_mod.sas.
Every effort made to test and verify accuracy of results.
*/ 

*-------------------------------------------------------------------;
/* INPUT A FEW DUMMY TEST CASES */

data test; 
INPUT sf1-sf12;
CARDS;
1 1 1 1 1 1 1 1 1 1 1 1 
1 1 3 3 3 3 3 3 3 3 3 3 
1 1 . 3 3 3 3 3 3 3 3 3 
5 5 1 1 1 . . . . . . . 
3 3 3 2 2 2 2 2 2 2 2 2
;
run;

/* clean out-of-range values */
data test; set test;
array pt5 sf1 sf8 sf12;
do over pt5;
if pt5 not in (1,2,3,4,5) then pt5=.;
end;

array pt3 sf2-sf3;
do over pt3;
if pt3 not in (1,2,3) then pt3=.;
end;

array pt2 sf4-sf7;
do over pt2;
if pt2 not in (1,2) then pt2=.;
end;

array pt6 sf9-sf11;
do over pt6;
if pt6 not in (1,2,3,4,5,6) then pt6=.;
end;
run;
*-------------------------------------------------------------------;
data test; set test;

/* Convert items 10 and 11 to version 2.0 */

rand1=uniform(-1);
rand2=uniform(-1);

sf11r=sf11;
If (sf11=2)                then sf11r=2 ;
If (sf11=3 and rand1 <0.5) then sf11r=2 ;
If (sf11=3 and rand1>=0.5) then sf11r=3;
If (sf11=4)                then sf11r=3 ;
If (sf11=5)                then sf11r=4 ;
If (sf11=6)                then sf11r=5 ;

sf10r=sf10;
If (sf10=2)                then sf10r=2 ;
If (sf10=3 and rand2 <0.5) then sf10r=2 ;
If (sf10=3 and rand2>=0.5) then sf10r=3;
If (sf10=4)                then sf10r=3 ;
If (sf10=5)                then sf10r=4;
If (sf10=6)                then sf10r=5 ;

/* end version conversion */

/* Physical functioning */
SFPhys=.;
IF (sf2=3)  then SFPhys = 1 ;
IF (sf2=2)  then SFPhys = 2 ;
IF (sf2=1)  then SFPhys = 3 ;

/* Role limitations */
SFRole=.;
IF (sf5=2 and sf6=2)  then SFRole = 1 ;
IF (sf5=1 and sf6=2)  then SFRole = 2 ;
IF (sf5=2 and sf6=1)  then SFRole = 3 ;
IF (sf5=1 and sf6=1)  then SFRole = 4 ;

/* Social functioning */
SFSocial=.;
IF (sf12=5) then SFSocial = 1 ;
IF (sf12=4) then SFSocial = 2 ;
IF (sf12=3) then SFSocial = 3 ;
IF (sf12=2) then SFSocial = 4 ;
IF (sf12=1) then SFSocial = 5 ;

/* Bodily pain */
SFpain=.;
IF (sf8=1) then SFPain = 1 ;
IF (sf8=2) then SFPain = 2 ;
IF (sf8=3) then SFPain = 3 ;
IF (sf8=4) then SFPain = 4 ;
IF (sf8=5) then SFPain = 5 ;

/* Mental health */
SFMental=.; 
IF (sf11r=5) then SFMental= 1 ;
IF (sf11r=4) then SFMental= 2 ;
IF (sf11r=3) then SFMental= 3 ;
IF (sf11r=2) then SFMental= 4 ;
IF (sf11r=1) then SFMental= 5 ;

/* Vitality */
SFVital=.;
If (sf10r=1) then SFVital = 1 ;
If (sf10r=2) then SFVital = 2 ;
If (sf10r=3) then SFVital = 3 ;
If (sf10r=4) then SFVital = 4 ;
If (sf10r=5) then SFVital = 5 ;

most=0;
if SFPhys   in (3)     or 
   SFRole   in (3,4)   or
   SFSocial in (4,5)   or
   SFPain   in (4,5)   or
   SFMental in (4,5)   or
   SFVital  in (4,5)   then most=1;

/* Weighting */

If (SFPhys=1) then pf1 =     0 ;
IF (SFPhys=2) then pf1 =     0 ;
IF (SFPhys=3) then pf1 = -.045 ;

If (SFRole=1) then rl1 =     0 ;
IF (SFRole=2) then rl1 = -.063 ;
IF (SFRole=3) then rl1 = -.063 ;
IF (SFRole=4) then rl1 = -.063 ;

IF (SFSocial=1) then sc1 =     0 ;
IF (SFSocial=2) then sc1 = -.063 ;
IF (SFSocial=3) then sc1 = -.066 ;
IF (SFSocial=4) then sc1 = -.081 ;
IF (SFsocial=5) then sc1 = -.093 ;

If (SFPain=1) then pn1 =     0 ;
IF (SFPain=2) then pn1 =     0 ;
IF (SFPain=3) then pn1 = -.042 ;
IF (SFPain=4) then pn1 = -.077 ;
IF (SFPain=5) then pn1 = -.137 ;

If (SFMental=1) then mh1 =     0 ;
IF (SFMental=2) then mh1 = -.059 ;
IF (SFMental=3) then mh1 = -.059 ;
IF (SFMental=4) then mh1 = -.113 ;
IF (SFMental=5) then mh1 = -.134 ;

IF (SFVital=1) then v1 =     0 ;
IF (SFVital=2) then v1 = -.078 ;
IF (SFVital=3) then v1 = -.078 ;
IF (SFVital=4) then v1 = -.078 ;
IF (SFVital=5) then v1 = -.106 ;

if most=0 then mst1 =     0;
if most=1 then mst1 = -.077;

SF12ind = 1 + pf1+rl1+sc1+pn1+mh1+v1+mst1 ;
run;
*-------------------------------------------------------------------;
TITLE "SF6d using SF12v1 (US)";
proc means maxdec=2 data=test;
  var pf1 rl1 sc1 pn1 mh1 v1 mst1 SF12ind ;  
run;