%LET ST=NY; * SET TO (UPPER CASE) 2-LETTER STATE ABBREVIATION;
%LET YRS=91; * set one or more 2-digit years, separated by asterisks, as in yrs=99*00*01;
%LET DATADIR=C:\PROJECTS\SPARCS DATA\NY; * Set to the subdirectory that has your hospital data, WITHOUT the final backslash;
%LET OUTDIR=C:\COD-DBECK\AHRQ\Output; * Set to the subdirectory for output, WITHOUT a final backslash;
%LET POPDS=pop; * Set to the name of your dataset with population counts in age/sex/zip groups;
%LET DORATE=Y; * Set to Y to make rate-based spreadsheets in addition to a hospital discharges file with an ACS flag,
                 or N to just create the hospital discharges file;

/*
Run this from a subdirectory in  which you've put:
 This SAS program.
 The SAS formats file.
 The population file(s).
*/

/* hospital discharge dataset names should be in the form: STYY, as in NY97, plus the SAS extension */


/* DO NOT ALTER ANYTHING BELOW THIS LINE !!!!!! */

/*__________________________________________________________________________________*/

/* Begin special flags */


%let mode=RATES; * Set to (UPPER CASE) RATES or COUNTS;
%let makedis=Y; * Set to Y to make the diseases dataset;
%let debug=N; * Set to Y to ENDSAS after one iteration of the inner loop;
%let tempdir=work; * Set to either WORK (to use SAS's work directory),
                     or a libname you have defined elsewhere, to hold interim data files;

/* End special flags */

/* Libnames:
LIBRARY has formats.
IN holds the raw hospital data, whose name is in the form STYY, e.g., NY97.
HERE holds everything else, including the Access Pop, and interim files.
*/

x md &outdir ;

libname out "&outdir";
libname library '.' ;
libname here1 v7 '.' shortfileext;
libname here2 v7 '.';
libname here (here1,here2);
LIBNAME IN "&datadir" ;

options compress=yes MPRINT source source2 linesize=256 PAGESIZE=66 noxwait xmin nofmterr;

/* BEGIN MACROS (USED TO BE MACROS.SAS): */

 %macro age(from, to) ;
  (&from le AGE le &to)
 %mend age ;

 %macro prim_dx(from, to) ;
    ("&from" le DCODE le "&to")
 %mend prim_dx ;

 %macro sec_dx(from, to) ;
  ( %do i=2 %to &dmax;
     %if &i > 2 %then OR ;
     ("&from" le DCODE&i le "&to")
    %end;
  )
 %mend sec_dx ;

 %macro drg(from, to) ;
   (&from le DRG     le &to)
 %mend drg ;

 %macro prm_proc(from, to) ;
    ("&from" le PCODE    le "&to")
 %mend prm_proc ;

 %macro sec_proc(from, to) ;
  ( %do i=2 %to &pmax;
     %if &i > 2 %then OR ;
     ("&from" le PCODE&i le "&to")
    %end;
  )
 %mend sec_proc ;

 %macro lostay(from, to) ;
   (&from le LOS le &to)
 %mend lostay ;

 %macro dis_stat(value) ;
   (PSCODE = &value)          /* numeric, 13jun01 taf */
 %mend dis_stat ;

 %macro sex(value) ; /* modified 02mar00 taf */
   (SEXrecod = "&value")
 %mend sex ;

 %macro secdin/parmbuff;
  ( %do i=2 %to &dmax;
     %if &i > 2 %then OR ;
     DCODE&i in: &syspbuff
    %end;
  )
 %mend secdin ;

 %macro secpin/parmbuff;
  ( %do i=2 %to &pmax;
     %if &i > 2 %then OR ;
     PCODE&i in: &syspbuff
    %end;
  )
 %mend secpin ;

/* END MACROS.SAS */


%LET FIPS= %sysfunc(putc(&st, $st2fips.)) ;

proc summary nway data=here.&popds;
 class aage;
 output out=temp(drop=_freq_ _type_);
run;

data aage;
 length aage $ 7;
 set temp;
 retain type    'N'
        fmtname 'AAGEFMT' ;
 start = input(substr(aage,2,2),2.);
 end   = input(substr(aage,5,2),2.);
 if end ge 99 then end=150; * To capture ages > 99;
 rename aage=label;
run;

proc format cntlin=aage LIBRARY=LIBRARY ;
 value diagfmt 1 = 'All_ACS';
run ;

data &tempdir..sparse; * keep one record per disease to add to binned disease records to make sure every disease is represented;
 length disease 3;
 retain disease 1 count 0 zipcode 'DUMMY' sex 'U' aage 'DUMMYY';
 format disease diagfmt.;
run;

data fts;
 input from to sex $;
cards;
  0  4 F
  0 17 F
  0 64 F
  1  4 F
  5  9 F
  5 14 F
  5 17 F
 10 14 F
 15 17 F
 18 39 F
 18 64 F
 40 64 F
 65 99 F
  0  4 A
  0 17 A
  0 64 A
  1  4 A
  5  9 A
  5 14 A
  5 17 A
 10 14 A
 15 17 A
 18 39 A
 18 64 A
 40 64 A
 65 99 A
  0  4 M
  0 17 M
  0 64 M
  1  4 M
  5  9 M
  5 14 M
  5 17 M
 10 14 M
 15 17 M
 18 39 M
 18 64 M
 40 64 M
 65 99 M
;
run;

data _null_;
 set fts end=lastrec;
 call symput('FROM'||left(_n_),from);
 call symput('TO'||left(_n_),to);
 call symput('SEX'||left(_n_),sex);
 if lastrec then call symput('TopRun',trim(left(put(_n_,8.))));
run;

%put State for all runs (st)   = &st ;
%put FIPS  for all runs (fips) = &fips ;
%put All years for all runs (yrs)  = &yrs ;
%put mode for all runs (mode - should be RATES or COUNTS) = &mode;
%put number of age/sex worksheets per run (TopRun) = &toprun;

%macro RunAll;

%let Loop=1;
%let yr=%scan(&yrs,&Loop,*);

%do %while(&yr ne);

%if &yr=98 or &yr=99 or &yr=00 or &yr=01 or &yr=02 or &yr=03 or &yr=04 %then %LET FMTYR=98;
%else %LET FMTYR=92;

%if &yr=00 or &yr=01 or &yr=02 or &yr=03 or &yr=04 %then %LET CCYY=20&yr;
%else %LET CCYY=19&yr;

%put Iteration Number for macro RunAll (Loop) = &Loop ;
%put Data year for this iteration (YR) = &yr ;
%put Full 4-digit year for this iteration (CCYY) = &ccyy;
%put Format year for this iteration (fmtyr) = &fmtyr ;
%put Make disease micro-dataset? (makedis) = &makedis ;

 /* Determine # of DX's, PROC's, and set macro vars       */
 /*   DMAX and PMAX dynamically ... 21mar01 taf           */


%if &makedis=Y %then %do;

proc contents NOPRINT data=IN.&st&YR       out=vars(keep=name) ;
run ;

data _null_ ;
 if lastrec then do ;
   call symput('DMAX', put(dx, 3.)) ;
   call symput('PMAX', put(px, 3.)) ;
   end ;

 SET VARS END=LASTREC ;
 if upcase(name) =: 'DCODE'  then dx+1 ;
 if upcase(name) =: 'PCODE'  then px+1 ;
 run ;

 %put macrovar DMAX    = &DMAX ;
 %put macrovar PMAX    = &PMAX ;

run;

 data out.dx&ST&YR (drop=sexrecod);
  set in.&st&YR;

 IF SEX IN('M' 'F') and (0 LE AGE LE 150) ;
 if age gt 99 then age = 99;

 if put(zipcode, $Z&FMTYR&ST..   ) ne '_OK_' then do ; /* zip is not in the state in this year */
*   output WORK.nomk ;
   delete;
 end ;

 length disease 3;
 format disease diagfmt. ;
 label disease = 'Disease Category' ;

 length AAGE $ 6 ;
 AAGE = put(age, aagefmt.) ;

 /*** sex of `1` is F in diag.sas,   ... 01mar00 taf        ***/
 length SEXrecod $ 1 ;
 if sex='M' then sexrecod='2' ;
 else sexrecod='1' ;


 /* begin definition of ACS conditions */

 /*BEGIN_CX("Immunization","Immunization")*/
    if dcode in: ('033','390','391','037','045')

 /*BEGIN_CX("Hemophilius","Hemophilius")*/
    or (dcode =: "3200" AND %AGE(1,5))  /* added a zero -- tod, 6/19/00 */

 /*BEGIN_CX("Grandmal","Grandmal")*/
    or dcode =: '345'

 /*BEGIN_CX("Convulsions","Convulsions")*/
    or dcode =: '7803'

 /*BEGIN_CX("ENT Infect","ENT Infections")*/
    or (dcode in: ('382','462','463','465','4721')
    AND NOT
    (pcode = '2001' OR
    %SECPIN("2001") ))

 /*BEGIN_CX("Pulmonary TB","Pulmonary Tuberculosis")*/
    or dcode =: '011'

 /*BEGIN_CX("Other TB","Other Tuberculosis")*/
    or %PRIM_DX(012,01899)

 /*BEGIN_CX("COPD","Chronic Obstructive Pulm Disease")*/
    or (dcode in: ('491','492','494','496') OR
    (dcode =: '4660' AND
    %SECDIN("491","492","494","496") ))

 /*BEGIN_CX("Bact Pneumo","Bacterial Pneumonia")*/
    or (dcode in: ('481','4822','4823','4829','483','485','486')
    AND NOT %SECDIN("2826"))

 /*BEGIN_CX("Asthma","Asthma")*/
    or dcode =: '493'

 /*BEGIN_CX("CHF","Congestive Heart Failure")*/
    or (dcode in: ("428","40201","40211","40291","5184")
    AND NOT
    (pcode in: ("3601","3602","3605","361","375","377")
    OR
    %SECPIN("3601","3602","3605","361","375","377")))

 /*BEGIN_CX("Hypertension","Hypertension")*/
    or (dcode in: ("4010","4019","40200","40210","40290")
    AND NOT
    (pcode in: ("3601","3602","3605","361","375","377")
    OR
    %SECPIN("3601","3602","3605","361","375","377")))

 /*BEGIN_CX("Angina","Angina")*/
    or (dcode in: ("4111","4118","413")
    AND NOT
   (%prm_proc(1,8699)OR
    %SEC_PROC(1,8699)))

 /*BEGIN_CX("Cellulitis","Cellulitis")*/
    or ((%PRIM_DX(681,68399) OR
    %PRIM_DX(686,68699)) AND
    NOT (%prm_proc(1,8599) OR %SEC_PROC(1,8599) OR
    %prm_proc(861,8699) OR %SEC_PROC(861,8699)))

 /*BEGIN_CX(Skin Grafts not using DRG`s */   /* 20mar01 taf */
    or (
    (
    %PRIM_DX(68100,68102) OR
    %PRIM_DX(68110,68111) OR
    %PRIM_DX(6820, 6829 ) OR
    %PRIM_DX(7070, 7071 ) OR
    %PRIM_DX(7078, 7079 )
    )
    and
    (
    %prm_proc(8582,8585) OR %SEC_PROC(8582,8585) or
    %prm_proc(8622,8622) OR %SEC_PROC(8622,8622) or
    %prm_proc(864, 864 ) OR %SEC_PROC(864, 864 ) or
    %prm_proc(8660,8663) OR %SEC_PROC(8660,8663) or
    %prm_proc(8665,8666) OR %SEC_PROC(8665,8666) or
    %prm_proc(8669,8675) OR %SEC_PROC(8669,8675) or
    %prm_proc(8691,8691) OR %SEC_PROC(8691,8691) or
    %prm_proc(8693,8693) OR %SEC_PROC(8693,8693)
    ))

 /*BEGIN_CX("Diabetes A","Diabetes A")*/
    or %PRIM_DX(2501,25039)

 /*BEGIN_CX("Diabetes B","Diabetes B")*/
    or %PRIM_DX(2508,25099)

 /*BEGIN_CX("Diabetes C","Diabetes C")*/
    or %PRIM_DX(250,25009)

 /*BEGIN_CX("Hypoglycemia","Hypoglycemia")*/
    or %PRIM_DX(2512,25129)

 /*BEGIN_CX("Gastroenteritis","Gastroenteritis")*/
    or %PRIM_DX(5589,55899)

 /*BEGIN_CX("Kid_Infect","Kidney/Urinary Infection")*/
    or (%PRIM_DX(590,59099)OR
    %PRIM_DX(5990,59909)OR
    %PRIM_DX(5999,59999))

 /*BEGIN_CX("PrimDehydration","Primary Dehydration")*/
    or %PRIM_DX(2765,27659)

 /*BEGIN_CX("PrimAnemia","Primary Iron Deficiency Iron Anemia")*/
    or (%AGE(0,5) AND
    (%PRIM_DX(2801,28019)OR
    %PRIM_DX(2808,28099)))

 /*BEGIN_CX("PrimNutrition","Primary Nutritional Deficiencies")*/
    or (%PRIM_DX(260,26299) OR
    %PRIM_DX(268,26819))

 /*BEGIN_CX("Failure Thrive","Failure to Thrive")*/
    or (%PRIM_DX(7834,78349) AND %AGE(0,0))

 /*BEGIN_CX("PID","Pelvic Inflammatory Disease")*/
    or (%SEX(1) AND %PRIM_DX(614,61499) AND NOT
    (%prm_proc(683,6889)OR
     %SEC_PROC(683,6889)))

 /*BEGIN_CX("Dental","Dental Conditions")*/
    or (%PRIM_DX(521,52399) OR
    %PRIM_DX(525,52599) OR
    %PRIM_DX(528,52899))

 /*BEGIN_CX("SecDehydration","Secondary Dehydration")*/
    or %SEC_DX(2765,27659)

 /*BEGIN_CX("SecAnemia","Secondary Iron Deficiency Iron Anemia")*/
    or (%AGE(0,5) AND
    (%SEC_DX(2801,28019) OR
    %SEC_DX(2808,28099)))

 /*BEGIN_CX("SecNutrition","Secondary Nutritional Deficiencies")*/
    or (%SEC_DX(260,26299) OR
    %SEC_DX(268,26819))


 then disease = 1; /* End defn of ACS conditions */

RUN ;

%end;

%if &dorate=Y %then %do;

%do inner=1 %to &toprun;

%let outfr=&&from&inner;
%let outto=&&to&inner;
%let sex=&&sex&inner;

  /* Create     dataset which counts by zip, sex, age      */
  /*  and disease ...                                         */

proc freq noprint data=out.dx&ST&YR(keep=age sex zipcode disease aage);  /* 30may02 taf */
 where (&OUTFR le age le &OUTTO) %if (&sex=M) or (&sex=F) %then and (sex = "&SEX"); ;
 tables zipcode * sex * aage * disease / SPARSE out=&tempdir..stats2(drop=percent) ;
run ;

data &tempdir..stats2full;
 set &tempdir..stats2
     &tempdir..sparse;
run;

proc sort data=&tempdir..stats2full;
 by zipcode sex aage;
run;

proc transpose data=&tempdir..stats2full
                out=&tempdir..STATSb(where=(zipcode ne 'DUMMY') drop=_name_ _label_) ;
 by zipcode sex aage;
 id disease ;
 var count;
run ;

  /* Add Zip population                                       */
  /* PBYMZIP2 generated by popbygr3.sas                       */

data &tempdir..stats4;
 merge &tempdir..statsb(in=s)
       here.&popds.(keep=zipcode sex aage pop&ccyy);
 by zipcode sex aage ;
 if s ;

 f = input(substr(aage, 2, 2), 2.);
 t = input(substr(aage, 5, 2), 2.);
 from = max(f, &OUTFR) ;
 to   = min(t, &OUTTO) ;
 corrpop = pop&ccyy * (to-from+1) / (t-f+1) ;

 format corrpop 12. ;
 drop f t ;
 rename pop&ccyy = allpop;

run;

data &tempdir..stats8 ;
 set &tempdir..stats4(drop=allpop);
 length s1 s2          $  4
        stdpop            8;

 s1 = sex !! put((from-1), z3.) ;
 s2 = sex !! put(to  , z3.) ;

 IF FROM=0 THEN STDPOP = put(s2, $cumfmtA.) ;
 ELSE stdpop = put(s2, $cumfmtA.) - put(s1, $cumfmtA.) ;
 if stdpop = .  then do ; /* 1 or both fmt. values missing */
  put 'ER' 'ROR: both ends of range not in cum. std. table' ;
  abort abend 1 ;
 end ;
 drop s1 s2 from to;
run ;

proc sort noequals data=&tempdir..stats8;
 by zipcode sex aage;
run;

/* Hopefully the following won't find any dupes: */
/*
proc sort noequals nodupkey data=&tempdir..stats8(keep=zipcode sex aage) out=&tempdir..test;
 by zipcode sex aage;
run;
*/
  /* Roll up std. pop for each zip        */
  /* Merge back into main dataset.           */

proc summary nway data=&tempdir..stats8(keep=zipcode stdpop);
 class zipcode ;
 var stdpop ;
 output out=std(keep=zipcode stdsum)
 sum= stdsum ;
run ;

  /* Figure out the adjusted rates                */

data &tempdir..A&OUTFR._&OUTTO ;
 retain zipcode ;             /* to put first ... 01jun00 taf */
 length all_acs 8;
 format all_acs 8.6;

 merge &tempdir..stats8(drop=sex aage)
       std;
 by ZIPcode;

 array disvar(*) all_acs;
 array counttot(1);
 array stdrate(1);
 array crude(1);
 
 retain counttot STDRATE cpoptot;

 if first.zipcode then do ;
  cpoptot=.;
  do i=1 to hbound(disvar);
   counttot(i)=.;
   stdrate(i)=.;
  end;
 end ;

 cpoptot  = sum(cpoptot,  corrpop) ;

 do i=1 to hbound(disvar);
  counttot(i) = sum(counttot(i), disvar(i)) ;
  IF CORRPOP NE 0 THEN stdrate(i) = sum(stdrate(i),(disvar(i)/corrpop)*(stdpop/stdsum));
 end;
 if last.zipcode AND (CPOPTOT > 0) then do ;
  do i=1 to hbound(disvar);
   %if &mode = RATES %then %do ;
    disvar(i) = sum(0,STDRATE(i)  * 1000) ;
   %end ;
   %else %if &mode = COUNTS %then %do ;
    disvar(i) = sum(0,counttot(i)) ;
   %end ;
   crude(i)= (counttot(i) / cpoptot ) * 1000;
  end;
  corrpop = cpoptot;
  output ;
 end ;
  %if &mode = COUNTS %then %do;
   format _numeric_ comma9.;
  %end;
 drop i cpoptot stdpop stdsum stdrat: ;
 rename corrpop=pop&st&yr&sex&outfr._&outto;
run ;

x md &outdir.\&ST&YR&mode ;
x del "&outdir.\&ST&YR&mode\&st&yr&SEX._&outfr._&OUTTO..xls" ;

proc dbload dbms=excel data=&tempdir..A&outfr._&outto(drop=counttot: crude:);
 path="&outdir.\&ST&YR&mode\&st&yr&SEX._&outfr._&OUTTO..xls" ;
 putnames=yes;
 limit=0 ;
 load ;
run;

%if &debug = Y %then %do;
 endsas;
%end;

%END; * end of inner loop;

%end; * end of if dorate;

%let Loop=%eval(&Loop+1);
%let yr=%scan(&yrs,&Loop,*);
%end; * end of outer loop;

%mend RunAll;

%RunAll
