*================== Program: PSI_HOSP_COMPOSITE.SAS =====================;
*
*  DESCRIPTION:
*         Constructs a Patient Safety and Adverse Events Composite 
*         measure based on user defined weights.  The default weights are the
*         National Quality Forum endorsed 10 component harm adjusted
*         numerator weights.
*
*  VERSION: SAS QI V2020
*  RELEASE DATE: JULY 2020
*
*  USER NOTE:  Requires output from PSI_HOSP_RISKADJ.SAS
*
*========================================================================;

%LET ARRY = ARRYP3;

*===================================================================;
* Import PSI Composite Weights                                    --;
* Weights sum to 1.0                                              --;
*===================================================================;
%include MacLib(PSI_HOSP_Composite_Wt_v2020.sas);
%setweights;

*===================================================================;
*  COMPUTE COMPOSITE                                              --;
*===================================================================;

data OUTHCOMP.&OUTFILE_COMP.(keep=HOSPID COMP1 COMP1VAR COMP1SE COMP1WHT COMP1LB COMP1UB);
set OUTHRISK.&OUTFILE_HOSPRISK.;

*-- Load Component Reference Rate and Signal Variance Arrays -- ;
%include MacLib(&PSCOMPRR.);

array ARRY4{10}
   RPPS03 RPPS06 RPPS08 RPPS09 RPPS10
   RPPS11 RPPS12 RPPS13 RPPS14 RPPS15
;

array ARRY6{10}
   VPPS03 VPPS06 VPPS08 VPPS09 VPPS10
   VPPS11 VPPS12 VPPS13 VPPS14 VPPS15
;

array ARRY7{10}
   APPS03 APPS06 APPS08 APPS09 APPS10
   APPS11 APPS12 APPS13 APPS14 APPS15
;

array ARRY12{10} _temporary_
   (&W03. &W06. &W08. &W09. &W10.
    &W11. &W12. &W13. &W14. &W15.)
;

array ARRY13{10}
   PPPS03 PPPS06 PPPS08 PPPS09 PPPS10
   PPPS11 PPPS12 PPPS13 PPPS14 PPPS15
;

do I = 1 TO 10;
   if ARRY13(I) GE 3 then do;
      ARRY6(I) = ARRY6(I) / (&ARRY.(I) * &ARRY.(I));
      do J = I TO 10;
         IDX = ARRY10(I,J);
         if I = J then ARRY7(I) = ARRY1(IDX) / (ARRY1(IDX) + ARRY6(I));
      end;
   end;
   else do;
      do J = I TO 10;
         IDX = ARRY10(I,J);
         if I = J then ARRY7(I) = 0;
      end;
   end;
end;

COMP1    = 0;
COMP1VAR = 0;
COMP1SE  = 0;
COMP1WHT = 0;

do I = 1 TO 10;
   if ARRY13(I) GE 3 then do;
      COMP1 = COMP1 + (ARRY12(I) * (((ARRY4(I) / &ARRY.(I)) * ARRY7(I)) + (1 - ARRY7(I))));
      COMP1WHT = COMP1WHT + (ARRY12(I) * ARRY13(I));
   end;
   else do;
      COMP1 = COMP1 + ARRY12(I);
      COMP1WHT = COMP1WHT + 0;
   end;
   do J = I TO 10;
      IDX = ARRY10(I,J);
      if I = J then COMP1VAR = COMP1VAR
      + (ARRY12(I) * (ARRY1(IDX) * (1 - ARRY7(I))) * ARRY12(J));
      else COMP1VAR = COMP1VAR
      + (ARRY12(I) * (ARRY1(IDX) * (1 - ARRY7(I)) * (1 - ARRY7(J))) * ARRY12(J));
   end;
end;

COMP1SE  = SQRT(COMP1VAR);
COMP1LB  = COMP1 - 1.96* COMP1SE;
COMP1UB  = COMP1 + 1.96* COMP1SE;



label
  COMP1    = 'PSI 90 Patient Safety and Adverse Events Composite'
  COMP1VAR = 'PSI 90 Patient Safety and Adverse Events Composite (Variance)'
  COMP1SE  = 'PSI 90 Patient Safety and Adverse Events Composite (SE)'
  COMP1WHT = 'PSI 90 Patient Safety and Adverse Events Composite (Weighted Denominator)'
  COMP1LB  = 'PSI 90 Patient Safety and Adverse Events Composite (Lower CL)'
  COMP1UB  = 'PSI 90 Patient Safety and Adverse Events Composite (Upper CL)';

run;



%MACRO PRT;

%IF &PRINT. = 1 %THEN %DO;

proc Means data=OUTHCOMP.&OUTFILE_COMP. n mean;
title 'PATIENT SAFETY AND ADVERSE EVENTS COMPOSITE';
var COMP1 COMP1VAR COMP1SE COMP1WHT;
run;

%END;

%MEND;

%PRT;
