* RSI Calculation for Web Use Rev 2.sps .

* Version 2.0 .

* Oct. 26, 2010.

* This SPSS routine creates a set of RSI variables given a set of ICD-9-Codes.

* It must be run in SPSS Version 15 or greater.

* The following directory structure and file placement is expected.

* Folder: .
*   c:\spss\temp .

* The following ancillary files must be in the folder c:\spss\temp : .
*   All Proc - Step 4 - 1YRPOD - May-20-10.sav .
*   All Proc - Step 4 - 30DLOS - May-20-10.sav .
*   All Proc - Step 4 - 30DPOD - May-20-10.sav .
*   All Proc - Step 4 - INHOSP - May-20-10.sav .
*   DP - ICD-9CM Code Labels v19 - v27 with CCS.sav .
*   sample data rev2.sav .


* The input file is: .
*   sample data rev2.sav .

* It is important that the data format of the input file be identical to that of 'sample data rev.sav'.
* The ICD-9-CM codes must be 6-character string variables.  Each code has a single-character prefix,
* which is D for diagnosis codes and P for procedure codes. Leading zeroes are preserved and
* decimals are not used.  For example, diagnosis code 123.45 must appear as D12345 and
* procedure code 3.2 must appear as P032.

* The names of the ICD-9-CM variables must be passed to the !riskbuild routine as shown in the
* argument INCODES in the call at this file.

* The output file is:
*   sample results rev2.sav .


* =======================================================================================.
* =======================================================================================.
SET MEXPAND ON.
SET MPRINT ON.

* =======================================================================================.
* =======================================================================================.
*** Macro to Load Betas for Diagnostic and Procedure Codes


DEFINE !betaload  (betatype    = !ENCLOSE('(', ')')
                   /betafile   = !ENCLOSE('(', ')')
                   /datadir    = !ENCLOSE('(', ')')).

*** Merge Betas Using 5, 4 and 3 Digit Codes.

String dp_code_cox (A6).
COMPUTE dp_code_cox = dp_code.
EXE.


*** Load 5 Digit Code Betas First.

SORT CASES dp_code_cox (A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!datadir,!betafile,'.sav"')
 /BY dp_code_cox.
EXECUTE.

RENAME VARIABLES (beta = dp_code_beta).
IF (SYSMIS(dp_code_beta) = 0) dp_code_beta_level = 5.
EXE.


*** Load 4 Digit Code Betas 2nd.

COMPUTE dp_code_cox = "".
IF (SYSMIS(dp_code_beta) = 1) dp_code_cox = SUBSTR(dp_code, 1, 5).
EXE.

SORT CASES dp_code_cox (A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!datadir,!betafile,'.sav"')
 /BY dp_code_cox.
EXECUTE.

IF (SYSMIS(dp_code_beta) = 1) dp_code_beta = beta.
IF (SYSMIS(beta) = 0) dp_code_beta_level = 4.
EXE.
DELETE VARIABLES beta.


*** Load 3 Digit Code Betas Last.

COMPUTE dp_code_cox = "".
IF (SYSMIS(dp_code_beta) = 1) dp_code_cox = SUBSTR(dp_code, 1, 4).
EXE.

SORT CASES dp_code_cox (A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!datadir,!betafile,'.sav"')
 /BY dp_code_cox.
EXECUTE.

IF (SYSMIS(dp_code_beta) = 1) dp_code_beta = beta.
IF (SYSMIS(beta) = 0) dp_code_beta_level = 3.
EXE.
DELETE VARIABLES beta.
DELETE VARIABLES dp_code_cox.


*** Set Remaining Missing Betas to 0.

IF (SYSMIS(dp_code_beta) = 1) dp_code_beta = 0.
EXE.

 
*** Rename Beta Variables Using Beta Type Suffix Passed in Macro Call.

RENAME VARIABLES (dp_code_beta = !CONCAT('beta_', !betatype)).
FORMAT !CONCAT('beta_', !betatype) (F8.4).

RENAME VARIABLES (PopBeta = !CONCAT('PopBeta_', !betatype)).
FORMAT !CONCAT('PopBeta_', !betatype) (F8.4).

DELETE VARIABLES dp_code_beta_level.

!ENDDEFINE.




* =======================================================================================.
* =======================================================================================.
SET MEXPAND ON.
SET MPRINT ON.

* =======================================================================================.
* =======================================================================================.
* Macro to Generate the Risk Adjustment Models (RSI) for a Database

* =======================================================================================.
* =======================================================================================.

DEFINE !riskbuild (incodes     = !ENCLOSE('(', ')')
                   /inputfile   = !ENCLOSE('(', ')')
                   /outputfile    = !ENCLOSE('(', ')')
                   /tempdir    = !ENCLOSE('(', ')')).


* Load Case File .

GET FILE= !CONCAT('"',!tempdir,!inputfile,'.sav"').
EXECUTE.


* Process Case File Diagnosis and Procedure Codes by Stacking Them into a Single Variable
* dp_priority Will Be Used to Give Priority to Case File Codes Order is ascending
* with 0 = Highest Priority Assigned to Principal Diagnosis and Procedure .

STRING dp_source (A32).

!DO !i !IN (!incodes).
STRING dp_code (A6).
COMPUTE dp_code = !i.
COMPUTE dp_priority = 1.
COMPUTE dp_source = !CONCAT('"', !i, '"').
IF (dp_source = 'principal_procedure_ICD9CM' | dp_source = 'principal_diagnosis_ICD9CM') dp_priority = 0.
SAVE OUTFILE = !CONCAT('"',!tempdir,!i,'.sav"') /KEEP= patient_id dp_code dp_priority dp_source.
EXECUTE.
DELETE VARIABLES dp_code.
!DOEND.


* Create a Dummy File Containing the Same Variables as the Previous Stacked File but without any Data. 

GET FILE= !CONCAT('"',!tempdir,'principal_procedure_ICD9CM.sav"').
FILTER OFF.
USE ALL.
SELECT IF (patient_id = $sysmis).
EXECUTE.
SAVE OUTFILE = !CONCAT('"',!tempdir,'dummy.sav"').
EXECUTE.


* Merge Codes to the Dummy File Using ADD FILES .

GET FILE= !CONCAT('"',!tempdir,'dummy.sav"').
EXECUTE.

!DO !i !IN (!incodes).
ADD FILES FILE=* 
   /FILE = !CONCAT('"', !tempdir, !i, '.sav"').
!DOEND.


* Get Rid of Blank Code Cases .

FILTER OFF.
USE ALL.
SELECT IF(dp_Code ~= "").
EXECUTE .


*** Get Rid of Duplicate Diagnostic and Procedure Codes (patient, visit, op) By Keeping First Encounter .
*** Sort by dp_source Gives First Priority to Case File Codes .

SORT CASES patient_id(A) dp_priority(A) dp_code(A).
Save OUTFILE = !CONCAT('"', !tempdir, 'All_codes0', '.sav"').
EXE.

AGGREGATE
  /OUTFILE=*
  /BREAK=patient_id dp_Code
  /dp_priority = FIRST(dp_priority)
  /dp_source= FIRST(dp_source).

Save OUTFILE = !CONCAT('"', !tempdir, 'All_codes1', '.sav"').
EXE.


*** Merge In Code Labels - Use 3 Digit Base Code for Missing Labels .
*** Use Full Codes First for Labeling .

STRING dp_code_tmp (A6).
COMPUTE dp_code_tmp = dp_code.
EXE.
SORT CASES BY dp_code_tmp(A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!tempdir,'DP - ICD-9CM Code Labels v19 - v27 with CCS.sav"')
 /BY dp_Code_tmp
 /drop CCS_code_tmp CCS_label_tmp.
EXE.
RENAME VARIABLES (label = dp_code_label).
RENAME VARIABLES (long_label = dp_code_label_long).


** Use 3 Digit Base Code Labels in Empty Fields .

COMPUTE dp_code_tmp = SUBSTR(dp_code,1,4).
EXE.
SORT CASES BY dp_code_tmp(A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!tempdir,'DP - ICD-9CM Code Labels v19 - v27 with CCS.sav"')
 /BY dp_Code_tmp
 /drop CCS_code_tmp CCS_label_tmp.
EXECUTE.
IF (dp_code_label = "") dp_code_label = label.
IF (dp_code_label_long = "") dp_code_label_long = long_label.
EXE.
RENAME VARIABLES (dp_code_tmp label = dp_basecode dp_basecode_label).


** Load CCS Classifications .
** WARNING SOME CCF CODES HAVE ONE EXTRA or ONE LESS 0 .
** Match Exact Codes First Then 5, 4 and 3 Digits Using 0 Padding and Truncation .
** This Approach Addresses CCF Coding Anomalies and Insures CCS Matching for Most Codes .

STRING dp_code_tmp dp_code_tmp5 dp_code_tmp4 dp_code_tmp3 (A6).
COMPUTE dp_code_tmp = dp_code.
COMPUTE dp_code_tmp5 = CONCAT(RTRIM(dp_code), '000').
COMPUTE dp_code_tmp4 = SUBSTR(dp_code_tmp5, 1, 5).
COMPUTE dp_code_tmp3 = SUBSTR(dp_code_tmp5, 1, 4).
EXE.


** Match Codes As Is First .

SORT CASES BY dp_code_tmp(A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!tempdir,'DP - ICD-9CM Code Labels v19 - v27 with CCS.sav"')
 /BY dp_Code_tmp
 /drop label .
EXE.
RENAME VARIABLES (CCS_code_tmp CCS_label_tmp = CCS_code CCS_label).
DELETE VARIABLES dp_code_tmp.
EXE.


** Match Using 0 Padded 5 Digit Codes .

RENAME VARIABLES (dp_code_tmp5 = dp_code_tmp).
SORT CASES BY dp_code_tmp(A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!tempdir,'DP - ICD-9CM Code Labels v19 - v27 with CCS.sav"')
 /BY dp_Code_tmp
 /drop label .
EXE.
DO IF (CCS_code = "").
   COMPUTE CCS_code = CCS_code_tmp.
   COMPUTE CCS_label = CCS_label_tmp.
END IF.
EXE.
DELETE VARIABLES dp_code_tmp CCS_code_tmp CCS_label_tmp.
EXE.


** Match Truncated 4 Digit Codes .

RENAME VARIABLES (dp_code_tmp4 = dp_code_tmp).
SORT CASES BY dp_code_tmp(A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!tempdir,'DP - ICD-9CM Code Labels v19 - v27 with CCS.sav"')
 /BY dp_Code_tmp
 /drop label .
EXE.
DO IF (CCS_code = "").
   COMPUTE CCS_code = CCS_code_tmp.
   COMPUTE CCS_label = CCS_label_tmp.
END IF.
EXE.
DELETE VARIABLES dp_code_tmp CCS_code_tmp CCS_label_tmp.
EXE.


** Match Truncated 3 Digit Codes .

RENAME VARIABLES (dp_code_tmp3 = dp_code_tmp).
SORT CASES BY dp_code_tmp(A).
MATCH FILES /FILE=*
 /TABLE= !CONCAT('"',!tempdir,'DP - ICD-9CM Code Labels v19 - v27 with CCS.sav"')
 /BY dp_Code_tmp
 /drop label .
EXE.
DO IF (CCS_code = "").
   COMPUTE CCS_code = CCS_code_tmp.
   COMPUTE CCS_label = CCS_label_tmp.
END IF.
EXE.
DELETE VARIABLES dp_code_tmp CCS_code_tmp CCS_label_tmp.
EXE.


** Label Primary Procedure .

String principal_procedure (A6) principal_procedure_label (A64) principal_procedure_label_long (A256) .

DO IF (LTRIM(RTRIM(dp_source)) = 'principal_procedure_ICD9CM').
  COMPUTE principal_procedure = dp_code.
  COMPUTE principal_procedure_label = dp_code_label.
  COMPUTE principal_procedure_label_long = dp_code_label_long.
END IF.
EXE.

SORT CASES patient_id(A) principal_procedure(D).
DO IF (patient_id = LAG(patient_id, 1)).
  COMPUTE principal_procedure = LAG(principal_procedure, 1).
  COMPUTE principal_procedure_label = LAG(principal_procedure_label, 1).
  COMPUTE principal_procedure_label_long = LAG(principal_procedure_label_long, 1).
END IF. 
EXE.


** Label Primary Diagnosis and Assign CCS Classification .

String principal_diagnosis (A6) principal_diagnosis_label (A64) principal_diagnosis_label_long (A256)
       principal_diagnosis_CCS (A6) principal_diagnosis_CCS_label (A120).
DO IF (LTRIM(RTRIM(dp_source)) = 'principal_diagnosis_ICD9CM').
  COMPUTE principal_diagnosis = dp_code.
  COMPUTE principal_diagnosis_label = dp_code_label.
  COMPUTE principal_diagnosis_label_long = dp_code_label_long.
  COMPUTE principal_diagnosis_CCS = CCS_code.
END IF.
EXE.

SORT CASES patient_id(A) principal_diagnosis(D).
DO IF (patient_id = LAG(patient_id, 1)).
  COMPUTE principal_diagnosis = LAG(principal_diagnosis, 1).
  COMPUTE principal_diagnosis_label = LAG(principal_diagnosis_label, 1).
  COMPUTE principal_diagnosis_label_long = LAG(principal_diagnosis_label_long, 1).
  COMPUTE principal_diagnosis_CCS = LAG(principal_diagnosis_CCS, 1).
END IF. 
EXE.


*** Load the Betas from the 4 Models .

!betaload betatype  =(30DLOS)
          betafile  =(All Proc - Step 4 - 30DLOS - May-20-10)
          datadir   =(!tempdir).

!betaload betatype  =(INHOSP)
          betafile  =(All Proc - Step 4 - INHOSP - May-20-10)
          datadir   =(!tempdir).

!betaload betatype  =(30DPOD)
          betafile  =(All Proc - Step 4 - 30DPOD - May-20-10)
          datadir   =(!tempdir).

!betaload betatype  =(1YRPOD)
          betafile  =(All Proc - Step 4 - 1YRPOD - May-20-10)
          datadir   =(!tempdir).


*** Compute Complications Betas .
*** Patients with Primary Diagnosis as a Complication Are Not Flagged as Having a Complications .
*** Sort by dp_code Last to Maintain Consistent Sequential Order
*** if postop_days and dp_priority Are the Same for Multitple Codes .

SORT CASES patient_id(A) dp_priority(A) dp_code(A).
COMPUTE admissionfor_complication = 0.
COMPUTE INHOSP_complication = 0.
COMPUTE comp_beta_30DLOS = 0.
COMPUTE comp_beta_INHOSP = 0.
COMPUTE comp_beta_30DPOD = 0.
COMPUTE comp_beta_1YRPOD = 0.
EXE.

IF (SUBSTR(principal_diagnosis_CCS,1,4) = "D237" | SUBSTR(principal_diagnosis_CCS,1,4) = "D238") admissionfor_complication = 1.
DO IF ((SUBSTR(CCS_code,1,4) = "D237" | SUBSTR(CCS_code,1,4) = "D238") & admissionfor_complication = 0).
   COMPUTE INHOSP_complication = 1.
   COMPUTE comp_beta_30DLOS = beta_30DLOS.
   COMPUTE comp_beta_INHOSP = beta_INHOSP.
   COMPUTE comp_beta_30DPOD = beta_30DPOD.
   COMPUTE comp_beta_1YRPOD = beta_1YRPOD.
END IF.
EXE.


*** Compute beta_xxxxx_ce (Complications Excluded);
*** Excludes Likely Complicatons as Defined Earlier Using CCS classification .

COMPUTE beta_30DLOS_ce = beta_30DLOS.
COMPUTE beta_INHOSP_ce = beta_INHOSP.
COMPUTE beta_30DPOD_ce = beta_30DPOD.
COMPUTE beta_1YRPOD_ce = beta_1YRPOD.

DO IF (INHOSP_complication = 1).
   COMPUTE beta_30DLOS_ce = 0.
   COMPUTE beta_INHOSP_ce = 0.
   COMPUTE beta_30DPOD_ce = 0.
   COMPUTE beta_1YRPOD_ce = 0.
END IF.
EXE.


*** Aggregate the Results to a Single Line / Patient .

COMPUTE dummy_PopBeta = 1.
EXE.

SORT CASES patient_id (A)  dp_priority (A)  dp_code (A).
AGGREGATE
  /OUTFILE= !CONCAT('"', !tempdir, 'Agg0.sav"')
  /BREAK= patient_id
  /principal_diagnosis           =LAST(principal_diagnosis)
  /principal_diagnosis_label     =LAST(principal_diagnosis_label)
  /principal_diagnosis_label_long=LAST(principal_diagnosis_label_long)
  /principal_procedure           =LAST(principal_procedure)
  /principal_procedure_label     =LAST(principal_procedure_label)
  /principal_procedure_label_long=LAST(principal_procedure_label_long)
  /baseline_beta_30DLOS          =SUM(beta_30DLOS)
  /baseline_beta_INHOSP          =SUM(beta_INHOSP)
  /baseline_beta_30DPOD          =SUM(beta_30DPOD)
  /baseline_beta_1YRPOD          =SUM(beta_1YRPOD)
  /baseline_beta_30DLOS_ce       =SUM(beta_30DLOS_ce)
  /baseline_beta_INHOSP_ce       =SUM(beta_INHOSP_ce)
  /baseline_beta_30DPOD_ce       =SUM(beta_30DPOD_ce)
  /baseline_beta_1YRPOD_ce       =SUM(beta_1YRPOD_ce)
  /dummy_PopBeta                 =MAX(dummy_PopBeta).

AGGREGATE
  /OUTFILE= !CONCAT('"', !tempdir, 'Agg_PopBeta.sav"')
  /PRESORTED
  /BREAK= dummy_PopBeta
  /PopBeta_30DLOS                =MAX(PopBeta_30DLOS)
  /PopBeta_30DPOD                =MAX(PopBeta_30DPOD)
  /PopBeta_1YRPOD                =MAX(PopBeta_1YRPOD).


* Adjust the Summed Betas by the Covariate Means.

GET FILE = !CONCAT('"', !tempdir, 'Agg0.sav"').
EXE.

MATCH FILES /FILE=*
  /TABLE=!CONCAT('"', !tempdir, 'Agg_PopBeta.sav"')
  /BY dummy_PopBeta.
EXECUTE.

DELETE VARIABLES dummy_PopBeta .

COMPUTE baseline_beta_30DLOS = baseline_beta_30DLOS - PopBeta_30DLOS .
COMPUTE baseline_beta_30DPOD = baseline_beta_30DPOD - PopBeta_30DPOD .
COMPUTE baseline_beta_1YRPOD = baseline_beta_1YRPOD - PopBeta_1YRPOD .
COMPUTE baseline_beta_30DLOS_ce = baseline_beta_30DLOS_ce + 1.32016476 .
COMPUTE baseline_beta_30DPOD_ce = baseline_beta_30DPOD_ce - 0.42701108 .
COMPUTE baseline_beta_1YRPOD_ce = baseline_beta_1YRPOD_ce - 0.24124644 .
EXE.

DELETE VARIABLES PopBeta_30DLOS PopBeta_30DPOD PopBeta_1YRPOD .


* Rename and Relabel Variables .

RENAME VARIABLES ( baseline_beta_30DLOS baseline_beta_INHOSP baseline_beta_30DPOD baseline_beta_1YRPOD
                   baseline_beta_30DLOS_ce baseline_beta_INHOSP_ce baseline_beta_30DPOD_ce baseline_beta_1YRPOD_ce =
                   RSI_LOS RSI_INHOSP RSI_30Day RSI_1YR
                   RSI_LOS_ce RSI_INHOSP_ce RSI_30Day_ce RSI_1YR_ce ) .

VARIABLE LABEL principal_diagnosis              'Principal diagnosis'.
VARIABLE LABEL principal_diagnosis_label        'Principal diagnosis label'.
VARIABLE LABEL principal_diagnosis_label_long   'Principal diagnosis label (long format)'.
VARIABLE LABEL principal_procedure              'Principal procedure'.
VARIABLE LABEL principal_procedure_label        'Principal procedure label'.
VARIABLE LABEL principal_procedure_label_long   'Principal procedure label (long format)'.
VARIABLE LABEL RSI_LOS                          'RSI_LOS'.
VARIABLE LABEL RSI_INHOSP                       'RSI_INHOSP'.
VARIABLE LABEL RSI_30Day                        'RSI_30Day'.
VARIABLE LABEL RSI_1YR                          'RSI_1YR'.
VARIABLE LABEL RSI_LOS_ce                       'RSI_LOS - excluding complications'.
VARIABLE LABEL RSI_INHOSP_ce                    'RSI_INHOSP - excluding complications'.
VARIABLE LABEL RSI_30Day_ce                     'RSI30Day - excluding complications'.
VARIABLE LABEL RSI_1YR_ce                       'RSI_1YR - excluding complications'.
  

SORT CASES patient_id(A).
SAVE OUTFILE = !CONCAT('"', !tempdir, !outputfile, '.sav"').
EXE.

GET FILE = !CONCAT('"', !tempdir, !outputfile, '.sav"').


* Clean up the Temporary Files.

ERASE FILE = !CONCAT('"', !tempdir, 'Agg0.sav"').
ERASE FILE = !CONCAT('"', !tempdir, 'Agg_PopBeta.sav"').
ERASE FILE = !CONCAT('"', !tempdir, 'All_codes0.sav"').
ERASE FILE = !CONCAT('"', !tempdir, 'All_codes1.sav"').
ERASE FILE = !CONCAT('"', !tempdir, 'dummy.sav"').

!DO !i !IN (!incodes).
ERASE FILE = !CONCAT('"',!tempdir,!i,'.sav"').
!DOEND.

!ENDDEFINE.




* =======================================================================================.
* =======================================================================================.
* Windows MACRO CALL .

!riskbuild
 incodes    = (principal_procedure_ICD9CM secondary_procedure_1_ICD9CM secondary_procedure_2_ICD9CM 
              secondary_procedure_3_ICD9CM secondary_procedure_4_ICD9CM secondary_procedure_5_ICD9CM
              secondary_procedure_6_ICD9CM secondary_procedure_7_ICD9CM secondary_procedure_8_ICD9CM 
              secondary_procedure_9_ICD9CM principal_diagnosis_ICD9CM secondary_diagnosis_1_ICD9CM 
              secondary_diagnosis_2_ICD9CM secondary_diagnosis_3_ICD9CM secondary_diagnosis_4_ICD9CM
              secondary_diagnosis_5_ICD9CM secondary_diagnosis_6_ICD9CM secondary_diagnosis_7_ICD9CM 
              secondary_diagnosis_8_ICD9CM secondary_diagnosis_9_ICD9CM)
 inputfile   = (sample data rev2)
 outputfile  = (sample results rev2)
 tempdir     = (c:\spss\temp\).
