 %MACRO E1210D1M(INP=, IND=, OUTDATA=, IDVAR=, KEEPVAR=, SEDITS=,
                 DATE_ASOF=, FMNAME=I12101Y09Y10YC, DF_DG=, DF_POSTG=);
 %**********************************************************************
 ***********************************************************************
 * E1210D1M creates HCC and score variables for each person who is
 * present in a person file.
 * If a person has at least one diagnosis in DIAG file then HCCs are
 * created, otherwise HCCs are set to 0 .
 *
 * Assumptions about input files:
 *   - both files are sorted by person ID
 *   - person level file has the following variables:
 *     :&IDVAR  - person ID variable (it is a macro parameter)
 *     :DOB     - date of birth
 *     :SEX     - gender
 *     :OREC    - original reason for entitlement
 *     :MCAID   - Medicaid dummy variable
 *     :NEMCAID - Medicaid dummy variable for new enrollees
 *
 *   - diagnosis level file has the following vars:
 *     :&IDVAR - person ID variable (it is macro parameter)
 *     :DIAG   - diagnosis
 *
 * Parameters:
 *      INP       - input person dataset
 *      IND       - input diagnosis dataset
 *      OUTDATA   - output dataset
 *      IDVAR     - name of person id variable (HICNO for Medicare data)
 *      KEEPVAR   - variables kept in output file
 *      SEDITS    - a switch that controls whether to perform edits on 
 *                  ICD9. 1-YES, 0-NO
 *      DATE_ASOF - reference date to calculate age. Set to February 1 
 *                  of the payment year for consistency with CMS.
 *      FMNAME    - version of format. For this version of the software
 *                  it is set to default FMNAME=I12101Y09Y10YC
 *      DF_DG     - normalization factor set by CMS, used to multiply 
 *                  dialysis and graft scores (currently set to 1 
 *                  by default)
 *      DF_POSTG  - normalization factor set by CMS, used to multiply 
 *                  post-graft scores (currently set to 1 by default)
 *
 * External macros:
 *      %AGESEXVR - create age/sex, originally disabled, disabled vars
 *      %EDITICD9 - perform edits to diagnosis
 *      %V12H70M  - assign one ICD9 to multiple CCs
 *      %V12H70L  - assign labels to HCCs
 *      %E12H70H  - set HCC=0 according to hierarchies
 *      %SCOREVAR - calculate a score variable
 *
 * Comment about format: 
 *   $I12101Y09Y10YC - is specific for this version of the software,
 *   and is a default value set to macro parameter FMNAME in this 
 *   macro
 *
 **********************************************************************;

 %**********************************************************************
 * step1: include external macros;
 **********************************************************************;
 %INCLUDE IN0(AGESEXVR)/SOURCE2;  %* create demographic variables;
 %INCLUDE IN0(EDITICD9)/SOURCE2;  %* perform edits;
 %INCLUDE IN0(V12H70L) /SOURCE2;  %* hcc labels;
 %INCLUDE IN0(E12H70H) /SOURCE2;  %* hierarchies;
 %INCLUDE IN0(V12H70M) /SOURCE2;  %* multiple CCs;
 %INCLUDE IN0(SCOREVAR)/SOURCE2;  %* calculate score variable;

 %**********************************************************************
 * step2: define internal macro variables;
 **********************************************************************;
              %****************************************
               * Macro variables common to all models
               *****************************************;

 %LET N_CC=189;    %*max # of HCCs;

  %*list of 70 HCCs included in the following models;
 %LET CMSHCC = %STR(HCC1    HCC2    HCC5   HCC7   HCC8   HCC9
                    HCC10   HCC15   HCC16  HCC17  HCC18  HCC19
                    HCC21   HCC25   HCC26  HCC27  HCC31  HCC32
                    HCC33   HCC37   HCC38  HCC44  HCC45  HCC51
                    HCC52   HCC54   HCC55  HCC67  HCC68  HCC69
                    HCC70   HCC71   HCC72  HCC73  HCC74  HCC75
                    HCC77   HCC78   HCC79  HCC80  HCC81  HCC82
                    HCC83   HCC92   HCC95  HCC96  HCC100 HCC101
                    HCC104  HCC105  HCC107 HCC108 HCC111 HCC112
                    HCC119  HCC130  HCC131 HCC132 HCC148 HCC149
                    HCC150  HCC154  HCC155 HCC157 HCC158 HCC161
                    HCC164  HCC174  HCC176 HCC177);
 %*all interactions with HCC variables;
 %LET Interactions_wHCC = %STR(D_HCC5 D_HCC44 D_HCC51 D_HCC52 D_HCC107
                               DM_CHF DM_CVD CHF_COPD COPD_CVD_CAD );

 %* Medicaid interactions with sex;
 %LET Medicaid_AgeSex_Interactions =
                 %STR(Medicaid_Female_Aged  Medicaid_Female_Disabled
                      Medicaid_Male_Aged    Medicaid_Male_Disabled);

               %****************************************
               * Community dialysis model
               *****************************************;
 %*age/sex cells;
 %LET AGESEX_DIAL=%STR(F0_34  F35_44 F45_54 F55_59 F60_64 F65_69
                       F70_74 F75_79 F80_84 F85_GT
                       M0_34  M35_44 M45_54 M55_59 M60_64 M65_69
                       M70_74 M75_79 M80_84 M85_GT);

 %* originally disabled interactions with sex;
 %LET Orig_Disabl_SexGE65_Interactions =
            %STR(OrigDisabled_Female_GE65   OrigDisabled_Male_GE65);

 %* originally  ESRD or both originally disabled & ESRD interactions
    with sex;
 %LET Orig_ESRD_Sex_Interactions =
                     %STR( Originally_ESRD_Female Originally_ESRD_Male);

 %*variables for Dialysis regression;
 %LET MOD_DIAL= %STR(&AGESEX_DIAL
                      &Medicaid_AgeSex_Interactions
                      &Orig_Disabl_SexGE65_Interactions
                      &Orig_ESRD_Sex_Interactions
                      &CMSHCC
                      &Interactions_wHCC);

               %****************************************
               * New Enrollees dialysis model
               *****************************************;
 %*age/sex cells;
 %LET AGESEX_DIAL_NE=%STR(NEF0_34  NEF35_44 NEF45_54 NEF55_59 NEF60_64
                          NEF65_69
                          NEF70_74 NEF75_79 NEF80_84 NEF85_GT
                          NEM0_34  NEM35_44 NEM45_54 NEM55_59 NEM60_64
                          NEM65_69
                          NEM70_74 NEM75_79 NEM80_84 NEM85_GT);

 %* Medicaid interactions with sex for New Enrollees;
 %LET NE_Medicaid_Age_Interactions =
                 %STR(NEMedicaid_Female_Aged NEMedicaid_Female_Disabled
                      NEMedicaid_Male_Aged   NEMedicaid_Male_Disabled);

 %* originally disabled interactions with sex for New Enrollees;
 %LET NE_OrigDisabl_Sex_Interactions =
                %STR(OrigDisabled_Female_LT65 OrigDisabled_Male_LT65);

 %*variables for Dialysis New Enrollees regression;
 %LET MOD_DIAL_NE = %STR(&AGESEX_DIAL_NE
                          &NE_Medicaid_Age_Interactions
                          &Orig_Disabl_SexGE65_Interactions
                          &NE_OrigDisabl_Sex_Interactions);

               %****************************************
               * Community Functioning Graft model
               *****************************************;

 %*for functioning graft (institutional and community);
 %LET AGESEX_GRAFT=%STR(F0_34  F35_44 F45_54 F55_59 F60_64 F65_69
                        F70_74 F75_79 F80_84 F85_89 F90_94 F95_GT
                        M0_34  M35_44 M45_54 M55_59 M60_64 M65_69
                        M70_74 M75_79 M80_84 M85_89 M90_94 M95_GT);

 %* originally disabled interactions with sex;
 %LET Orig_Disabled_Sex_Interactions =
                     %STR(OrigDisabled_Female OrigDisabled_Male);

 %*variables for Functioning Graft Community regression;
 %LET MOD_GRAFT_COMM= %STR(&AGESEX_GRAFT
                           &Medicaid_AgeSex_Interactions
                           &Orig_Disabled_Sex_Interactions
                           &CMSHCC
                           &Interactions_wHCC);

               %****************************************
               * Institutional  Functioning Graft model
               *****************************************;

  %*variables for Functioning Graft Institutional regression;
 %LET MOD_GRAFT_INST= %STR(&AGESEX_GRAFT
                           MCAID ORIGDS
                           &CMSHCC
                           &Interactions_wHCC);

 **********************************************************************;
 * New Enrollees GRAFT model variables
 **********************************************************************;
 %LET NE_AGESEX =%STR(NEF0_34  NEF35_44 NEF45_54 NEF55_59 NEF60_64
                 NEF65 NEF66 NEF67 NEF68 NEF69
                 NEF70_74 NEF75_79 NEF80_84 NEF85_89 NEF90_94 NEF95_GT
                 NEM0_34  NEM35_44 NEM45_54 NEM55_59 NEM60_64
                 NEM65 NEM66 NEM67 NEM68 NEM69
                 NEM70_74 NEM75_79 NEM80_84 NEM85_89 NEM90_94 NEM95_GT);

 %LET NE_Demographic_Interactions = %STR(
             Medicaid_female0_64  Medicaid_female65 Medicaid_female66_69
             Medicaid_female70_74 Medicaid_female75_GT
             Medicaid_male0_64    Medicaid_male65   Medicaid_male66_69
             Medicaid_male70_74   Medicaid_male75_GT
             Origdis_female65     Origdis_female66_69
             Origdis_female70_74  Origdis_female75_GT
             Origdis_male65       Origdis_male66_69
             Origdis_male70_74    Origdis_male75_GT);

 %LET MOD_GRAFT_NE= &NE_AGESEX  &NE_Demographic_Interactions;

 %**********************************************************************
 * step3: merge person and diagnosis files outputting one record
 *        per person with score and HCC variables for each input person
 *        level record
 **********************************************************************;

 DATA &OUTDATA(KEEP=&KEEPVAR);
    %****************************************************;
    * step3.1: declaration section;
    %****************************************************;

    %V12H70L;  *HCC labels;

    %*length of some new variables,
     other demographic vars defined in macro AGESEXVR;
    LENGTH CC $4. AGEF 3.
           &AGESEX_DIAL
           DM CHF COPD CVD VD CAD &Interactions_wHCC
           &Medicaid_AgeSex_Interactions
           &Orig_Disabl_SexGE65_Interactions
           &Orig_ESRD_Sex_Interactions
           &NE_Medicaid_Age_Interactions
           &NE_OrigDisabl_Sex_Interactions
           &AGESEX_GRAFT
           &NE_AGESEX
           NEF85_GT
           NEM85_GT
           NEF65_69
           NEM65_69
           &Orig_Disabled_Sex_Interactions
           &NE_Demographic_Interactions
           CC1-CC&N_CC
           HCC1-HCC&N_CC        3.;

    %*retain cc vars;
    RETAIN CC1-CC&N_CC 0  AGEF
           ;
    %*arrays;
    ARRAY C(&N_CC)  CC1-CC&N_CC;
    ARRAY HCC(&N_CC) HCC1-HCC&N_CC;
    %*interactions with HCCs;
    ARRAY RV &Interactions_wHCC;

    %****************************************************
    * step3.2: bring regression parameters
    ****************************************************;
    IF _N_ = 1 THEN SET INCOEF.HCCCOEFN;

    %****************************************************
    * step3.3: merge
    ****************************************************;
    MERGE &INP(IN=IN1)
          &IND(IN=IN2);
    BY &IDVAR;

    IF IN1 THEN DO;

    %*******************************************************
    * step3.4: for the first record for a person set CC to 0
    ********************************************************;

       IF FIRST.&IDVAR THEN DO;
          %*set ccs to 0;
           DO I=1 TO &N_CC;
            C(I)=0;
           END;
           %*sas calculates age as 50.9999 instead of 51 in this case;
           IF DAY(DOB)=DAY(&DATE_ASOF) & MONTH(DOB)=MONTH(&DATE_ASOF)
           THEN _BIRTH=DOB - 1 ;
           ELSE _BIRTH=DOB;

           AGEF  =INT((&DATE_ASOF - _BIRTH)/ 365.25);
       END;

    %****************************************************
    * step3.5 if there are any diagnoses for a person
    *         then do the following:
    *         - create CC using format $I12101Y09Y10YC
    *         - perform ICD9 edits using macro EDITICD9
    *         - assign additional CC using V12H70M macro
    ****************************************************;
       IF IN1 & IN2 THEN DO;

           CC = LEFT(PUT(DIAG,$&FMNAME..));

           IF CC NE "-1.0" THEN DO;
              %IF &SEDITS = 1 %THEN
                %EDITICD9(ICD9=DIAG, AGE=AGEF); %*perform edits;
              IND=INPUT(CC,4.);
              IF 1<= IND <= &N_CC THEN DO;
                C(IND)=1;
                %V12H70M(ICD9=DIAG); %*multiple ccs;
              END;
           END;
       END; %*CC creation;

    %**************************************************************
    * step3.6 for the last record for a person do the
    *         following:
    *         - create demographic variables needed (macro AGESEXVR)
    *         - create HCC using hierarchies (macro E12H70H)
    *         - create HCC interaction variables
    *         - create HCC and DISABL interaction variables
    *         - set to 0 HCCs and interaction vars if there
    *           are no diagnoses for a person
    *         - create 14 score variables
    **************************************************************;
       IF LAST.&IDVAR THEN DO;

           %*****************************
           * demographic vars
           *****************************;
           %*create age/sex cells, originally disabled, disabled vars;
           %AGESEXVR(AGEF=AGEF, SEX=SEX, OREC=OREC);
           F85_GT = (SEX='2' & AGEF >84);
           M85_GT = (SEX='1' & AGEF >84);
           NEF85_GT = (SEX='2' & AGEF >84);
           NEM85_GT = (SEX='1' & AGEF >84);
           NEF65_69 = SUM(NEF65, NEF66, NEF67, NEF68, NEF69);
           NEM65_69 = SUM(NEM65, NEM66, NEM67, NEM68, NEM69);

           %*medicaid interactions;
           Medicaid_Female_Aged     = MCAID*(SEX='2')*(1 - DISABL);
           Medicaid_Female_Disabled = MCAID*(SEX='2')*DISABL;
           Medicaid_Male_Aged       = MCAID*(SEX='1')*(1 - DISABL);
           Medicaid_Male_Disabled   = MCAID*(SEX='1')*DISABL;

           %* originally disabled interactions with age/sex;
           %*from AGESEVR macro :ORIGDS=OREC IN ('1','3'))*(AGEF >= 65) ;
           OrigDisabled_Female   = ORIGDS * (SEX='2');
           OrigDisabled_Male     = ORIGDS * (SEX='1');
           OrigDisabled_Female_GE65 = (OREC='1')*(AGEF >= 65)*(SEX='2');
           OrigDisabled_Male_GE65   = (OREC='1')*(AGEF >= 65)*(SEX='1');
           OrigDisabled_Female_LT65  = (OREC='1')*(AGEF < 65)*(SEX='2');
           OrigDisabled_Male_LT65    = (OREC='1')*(AGEF < 65)*(SEX='1');

           %* originally  ESRD or both originally disabled & ESRD;
           Originally_ESRD_Female   = (OREC IN ('2','3'))*(SEX='2')*
                                      (AGEF >=65);
           Originally_ESRD_Male     = (OREC IN ('2','3'))*(SEX='1')*
                                      (AGEF >=65);

           %*****************************
           * variables for New Enrollees
           *****************************;
          %*Medicaid * AgeSex * Disabled;
           NEMedicaid_Female_Aged     = NEMCAID*(SEX='2')*(1 - DISABL);
           NEMedicaid_Female_Disabled = NEMCAID*(SEX='2')*DISABL;
           NEMedicaid_Male_Aged       = NEMCAID*(SEX='1')*(1 - DISABL);
           NEMedicaid_Male_Disabled   = NEMCAID*(SEX='1')*DISABL;

           %*Medicaid * AgeSex;
           Medicaid_female0_64   =(SEX="2" & NEMCAID & 0<=AGEF <65
                                    & NEF65=0);
           Medicaid_female65     =(SEX="2" & NEMCAID & NEF65);
           Medicaid_female66_69  =(SEX="2" & NEMCAID
                                    & sum(NEF66,NEF67,NEF68,NEF69));
           Medicaid_female70_74  =(SEX="2" & NEMCAID & 70<=AGEF <75);
           Medicaid_female75_GT  =(SEX="2" & NEMCAID & AGEF >74);
           Medicaid_male0_64     =(SEX="1" & NEMCAID & 0<=AGEF <65
                                    & NEM65=0);
           Medicaid_male65       =(SEX="1" & NEMCAID & NEM65);
           Medicaid_male66_69    =(SEX="1" & NEMCAID
                                    & sum(NEM66,NEM67,NEM68,NEM69));
           Medicaid_male70_74    =(SEX="1" & NEMCAID & 70<=AGEF <75);
           Medicaid_male75_GT    =(SEX="1" & NEMCAID & AGEF >74);

           %*Originally Disabled * AgeSex;
           Origdis_female65     =(SEX='2' & ORIGDS & NEF65);
           Origdis_female66_69  =(SEX='2' & ORIGDS
                                   & sum(NEF66,NEF67,NEF68,NEF69));
           Origdis_female70_74  =(SEX='2' & ORIGDS & 70 <= AGEF <75);
           Origdis_female75_GT  =(SEX='2' & ORIGDS & AGEF >74);

           Origdis_male65       =(SEX='1' & ORIGDS & NEM65 );
           Origdis_male66_69    =(SEX='1' & ORIGDS
                                   & sum(NEM66,NEM67,NEM68,NEM69));
           Origdis_male70_74    =(SEX='1' & ORIGDS & 70 <= AGEF <75);
           Origdis_male75_GT    =(SEX='1' & ORIGDS & AGEF >74);

           IF IN1 & IN2 THEN DO;
               %***************************
               * setting HCCs, hierarchies
               ***************************;
               %E12H70H;
               %*set ESRD HCCs to 0;
               HCC130=0;
               HCC131=0;
               %***************************
               * HCC interaction variables
               ***************************;
               %*interactions with disabled ;
               D_HCC5 =   DISABL*HCC5 ; *opportunistic infections;
               D_HCC44 =  DISABL*HCC44; *severe hematological disorders;
               D_HCC51 =  DISABL*HCC51; *drug/alcohol psychosis;
               D_HCC52 =  DISABL*HCC52; *drug/alcohol dependence;
               D_HCC107 = DISABL*HCC107;*cystic fibrosis;
               %*diagnostic categories;
               DM   = MAX (HCC15, HCC16, HCC17, HCC18, HCC19);
               CHF  = HCC80;
               COPD = HCC108;
               CVD  = MAX (HCC95, HCC96, HCC100, HCC101);
               VD   = MAX (HCC104, HCC105);
               CAD  = MAX (HCC81, HCC82, HCC83);
               %* interactions ;
               DM_CHF       =DM*CHF      ;
               DM_CVD       =DM*CVD      ;
               CHF_COPD     =CHF*COPD    ;
               COPD_CVD_CAD =COPD*CVD*CAD;

           END; %*there are some diagnoses for a person;
           ELSE DO;
              DO I=1 TO &N_CC;
                 HCC(I)=0;
              END;
              DO OVER RV;
                 RV=0;
              END;
           END;

           *to be able to keep normalization factors DF_DG and DF_POSTG in the output file;
           DF_DG = &DF_DG; 
           DF_POSTG = &DF_POSTG;
           LABEL
           DF_DG = "Normalization factor set by CMS, used to multiply dialysis and graft scores"
           DF_POSTG = "Normalization factor set by CMS, used to multiply post-graft scores";
          
           %*score calculation;
                                 
           /*********************************/
           /*    dialysis model             */
           /*********************************/;
          %SCOREVAR(PVAR=SCORE_DIAL, RLIST=&MOD_DIAL, CPREF=DI_);
           *normalization;
           SCORE_DIAL=&DF_DG*SCORE_DIAL;

           /**********************************/
           /*  dialysis new enrollees model  */
           /**********************************/;
          %SCOREVAR(PVAR=SCORE_DIAL_NE, RLIST=&MOD_DIAL_NE, CPREF=DNE_);
           *normalization;
           SCORE_DIAL_NE=&DF_DG*SCORE_DIAL_NE;

           /**********************************/
           /*   transplant scores            */
           /**********************************/;

          SCORE_TRANS_KIDNEY_ONLY_1M    = &DF_DG*TRANSPLANT_KIDNEY_ONLY_1M ;
          SCORE_TRANS_KIDNEY_ONLY_2M    = &DF_DG*TRANSPLANT_KIDNEY_ONLY_2M ;
          SCORE_TRANS_KIDNEY_ONLY_3M    = &DF_DG*TRANSPLANT_KIDNEY_ONLY_3M ;

          SCORE_TRANS_KIDNEY_PANCREAS_1M= &DF_DG*TRANSPLANT_KIDNEY_PANCREAS_1M;
          SCORE_TRANS_KIDNEY_PANCREAS_2M= &DF_DG*TRANSPLANT_KIDNEY_PANCREAS_2M;
          SCORE_TRANS_KIDNEY_PANCREAS_3M= &DF_DG*TRANSPLANT_KIDNEY_PANCREAS_3M;


           /*********************************/
           /*    community graft model      */
           /*********************************/;

          %SCOREVAR(PVAR=_SCORE_GRAFT_COMM, RLIST=&MOD_GRAFT_COMM,
                         CPREF=GC_);
          %*transplant bumps;
          SCORE_GRAFT_COMM_DUR4_9 =&DF_POSTG*(_SCORE_GRAFT_COMM +
                                   LT65_DUR4_9 * (AGEF < 65) +
                                   GE65_DUR4_9 * (AGEF >= 65));

          SCORE_GRAFT_COMM_DUR10PL =&DF_POSTG*(_SCORE_GRAFT_COMM +
                                    LT65_DUR10PL * (AGEF < 65) +
                                    GE65_DUR10PL * (AGEF >= 65));

           /*********************************/
           /*    institutional graft model  */
           /*********************************/;

          %SCOREVAR(PVAR=_SCORE_GRAFT_INST, RLIST=&MOD_GRAFT_INST,
                         CPREF=GI_);

          %*transplant bumps;
          SCORE_GRAFT_INST_DUR4_9 =&DF_POSTG*(_SCORE_GRAFT_INST +
                                   LT65_DUR4_9 * (AGEF < 65) +
                                   GE65_DUR4_9 * (AGEF >= 65));

          SCORE_GRAFT_INST_DUR10PL =&DF_POSTG*(_SCORE_GRAFT_INST +
                                    LT65_DUR10PL * (AGEF < 65) +
                                    GE65_DUR10PL * (AGEF >= 65));

           /**********************************/
           /*   new enrollees graft model    */
           /**********************************/;

          %SCOREVAR(PVAR=_SCORE_GRAFT_NE, RLIST=&MOD_GRAFT_NE,
                         CPREF=GNE_);
          %*transplant bumps;
          SCORE_GRAFT_NE_DUR4_9 =&DF_POSTG*(_SCORE_GRAFT_NE +
                                 LT65_DUR4_9 * (AGEF < 65) +
                                 GE65_DUR4_9 * (AGEF >= 65));

          SCORE_GRAFT_NE_DUR10PL =&DF_POSTG*(_SCORE_GRAFT_NE +
                                  LT65_DUR10PL * (AGEF < 65) +
                                  GE65_DUR10PL * (AGEF >= 65));

          OUTPUT &OUTDATA;
       END; %*last record for a person;
     END; %*there is a person record;
 RUN;

 %**********************************************************************
 * step4: data checks and proc contents
 ***********************************************************************;
 PROC PRINT U DATA=&OUTDATA(OBS=46);
     TITLE "*** file outputted by ESRD software ***";
 RUN ;
 PROC CONTENTS DATA=&OUTDATA;
 RUN;

 %MEND E1210D1M;
