10 steps to easier sas code maintenance

Upload: jessica-hampton

Post on 07-Apr-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    1/9

    1

    10 Steps to Easier SAS Code Maintenance

    Jessica Hampton, CIGNA Corporation, Bloomfield, CT

    ABSTRACT

    Part of the authors job at CIGNA is to produce on a yearly basis a number of rates used in national healthcare

    quality surveys and accreditation performance measures. Each year when the revised specs came out, she gottired of having to update processes manually, hunting through programs for diagnosis codes and dates thatneeded to be changed, copying and pasting the same updates and code blocks so many times she lost count,and then inevitably finding out shed missed a spot when the program either bombed, or worse ran all the waythrough but returned last years data instead of this years or outdated diagnosis codes. Then when the revisionsto the revisions came out and those revised revisions begot new revisions as well, she had to keep going throughthe same tedious process.

    This paper describes how to make yearly code maintenance tasks easier in 10 steps, using simple organizationtechniques, appropriate documentation, macro variables, and parameterized macros.

    1. Break large processes into smaller steps.

    2. Number programs.

    3. Document using comments.

    4. Document using program headers.

    5. Create an initial startup program.

    6. Create a final cleanup program.

    7. Use macro variables for date selection criteria.

    8. Use macro variables for file naming.

    9. Use parameterized macros for similar processes.

    10. Use macro variables for long lists that need frequent updating/referencing.

    INTRODUCTION

    Some of the sections of this paper are targeted toward people in the health insurance industry who work withNCQA-like quality measures which tend to have similarities and variations around a common theme. Such meas-ures often include long lists of diagnoses and procedural codes which get updated on a yearly (or more frequent)basis. However, the larger point of the paper is applicable to many different fields: Think about how to organizeprograms and process flow before beginning a project (similar to outlining a paper before writing it), use macrovariables to store and reference regularly updated values (such as dates) in a consolidated fashion, and minimizecoding where possible with parameterized macros.

    BREAK UP LARGE PROCESSES

    Organize a large process flow by breaking it into logical steps; each smaller step should have its own program.This has the effect of separating a book into chapters, or a large block of text into paragraphs, increasingreadability. It makes code easier to maintain since the programmer doesnt have to scroll through thousands oflines of code crammed into one giant program in order to update code.

    NUMBER PROGRAMS

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    2/9

    2

    Once the process flow is organized into smaller programs, number programs in the order in which they should berun. This is like creating a table of contents or an index. Store each process flow in its own folder.

    DOCUMENT USING COMMENTS AND HEADERS

    A crucial step to making code easier to maintain (both for the original developer and for anyone else who inheritsthe code later on), is to liberally sprinkle it with comments. In addition, a program header should include at aminimum the name of the program, the developers name, date developed, a brief description of the purpose of

    the program, and information about any important updates (programmers name, date updated, and a brief de-scription). It also might include any input tables required or output filenames produced. Sample headers andcomments are shown in the examples included within the sections below.

    CREATE AN INITIAL STARTUP PROGRAM

    For a process flow that is made up of several smaller programs, it helps to create an initial startup program toestablish libnames, remote sessions, macro variables that will be referenced during the process, and systemoptions. The setup program in the screenshot below gets named 0_pgm_WHP_setup:

    A sample setup program is shown on the next page:

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    3/9

    3

    CREATE A FINAL CLEANUP PROGRAM

    At the end of the process, create a final program (numbered accordingly) to take care of cleanup: deleting anyinterim files created earlier in the process which are no longer necessary to store or downloading files that werecreated on a remote server. Here is also a good place to include statements to create a final table listing and ex-port a data dictionary to Excel, if desired (Charles Patridge).

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    4/9

    4

    A sample cleanup program looks like this:

    Including field lengths and file sizes in the data dictionary can help the programmer identify at a glance whichfields were inadvertently created or extracted with a longer length than needed to store the data (a 200 lengthfield used to store an 8 character string can have a large impact on the size of a file). This information can beused to edit programs later to decrease table sizes and minimize storage space, which is an important considera-tion when dealing with already large data sets.

    USE MACRO VARIABLES FOR DATE SELECTION CRITERIA

    The setup program created and initialized macro variables year, yearlast, yearmonth, startdate, birthyear, andbirthdate for later reference in the process. Using macro variables for date criteria in the WHERE clauses andCASE WHEN clauses of SELECT statements allows the programmer to update a date or date range once in asingle location (the setup program) rather than having to regularly update multiple dates sprinkled throughoutcode in multiple programs. Examples:

    where ben_feat_eff_dt &startdated;

    Case when HRA_Month_Start = 1

    Then &yearmonth + HRA_Month_Start

    Else &yearlastmonth + HRA_Month_Start

    End as HRA_Prog_Yr_Start,

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    5/9

    5

    USE MACRO VARIABLES FOR FILE NAMING

    Use macro variables to add dates to the end of file names when creating new files, referencing old files, and alsoto reference libraries where the path changes yearly or monthly based on date. Examples shown as follows:

    Create Table qry_Ben_Feat_&year as

    Proc Download Data = WHP.Internal_EPop_&year OUT=HRA.Internal_EPop_&year;

    Libname PPO /projects/hedis/ppo&year;

    USE PARAMETERIZED MACROS FOR SIMILAR PROCESSES

    Sometimes a developer will be asked to write source code which will be used to produce a set of related meas-ures on a regular production cycle. In order to avoid writing unnecessary code for processes which are essen-tially the same, a developer can perform an analysis by breaking down each measure into smaller pieces andseeing which pieces, if any, are commonly repeated with only slight variations (using a different set of diagnosiscodes, for example). The following chart organizes a set of 16 measures, grouping similar measures together:

    Measure Denominator Exclusions

    10,11,12,1

    3 continuously enrolled, 18+

    1,3,14,16

    continuously enrolled, 18+2+ outpatient/non-acute inpatient eventsOR 1+ ED/acute inpatient eventsw/diabetes principal or secondary diagnosis during meas-urement year or year priorOR pharmacy event w/diabetes-related prescription

    7,8,15

    continuously enrolled, 18+2+ outpatient/non-acute inpatient eventsOR 1+ ED/acute inpatient eventsw/hypertension/CHF/asthmaprincipal or secondary diagno-sis during measurement year or year prior

    2continuously enrolled, 18+w/appendicitis principal or secondary diagnosis

    5

    continuously enrolled, 18+2+ outpatient/non-acute inpatient eventsOR 1+ ED/acute inpatient eventsw/copd* principal or secondary diagnosis - some diagnosesonly qualify with secondary diagnosis codes

    Measure Numerator Exclusions

    1,3,10,14

    include discharges with principal diagnosis code specified:diabetes short term complications

    diabetes long term complicationshypovolemiauncontrolled diabetes transfers

    7*,8,13

    include discharges with principal diagnosis code specified:hypertensionCHFangina

    transferscardiac procedure codes inany field*For 7 only, also excludekidney disease diagnoses ifaccompanied by hemodialy-sis procs

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    6/9

    6

    11,12

    include discharges with principal diagnosis code specified:bacterial pneumoniaUTI

    transfersimmunocompromised stateproc codesimmunocompromised statediagnoses*For 11, also exclude ane-mia principal or secondarydiagnoses

    *For 12, also exclude princi-pal or secondary kidney dis-order diagnoses

    2include discharges with principal or secondary diagnosiscode for perforation or abscess of appendix transfers

    5

    include discharges with principal diagnosis code for COPD -certain diagnoses qualify only if accompanied by secondarydiagnosis transfers

    15 include discharges with principal diagnosis code for asthma

    transfersprincipal or secondary diag-noses of cystic fibrosis

    16

    include discharges with principal or secondary diagnosiscode for diabetesAND procedure code for lower-extremity amputation transfers

    Doing such an analysis can identify pieces which the developer can convert to parameterized macros to savetime coding. Not only does this save time coding initially for the developer, it also saves time maintaining thecode, allowing the programmer to revise a single macro rather than copying and pasting the revision in many dif-ferent places across several programs.

    In this case, each measure gets its own program, and initial and cleanup programs are also created. Here is anexample of the parameterized macro transfer which is then called twice (once for managed care and once forppo) by all 16 programs in creating the numerators:

    %macro transfer(filename=)/STORE SOURCE;

    /*identify and delete transfers from numerator*/CREATE TABLE &filename._TRANS AS

    SELECT B.conf_id, B.admit_dt, A.disch_dt

    FROM PQI.&filename A

    JOIN PQI.&filename B ON A.rhmo=B.rhmo AND A.bkey=B.bkey

    AND A.disch_dt BETWEEN B.admit_dt AND intnx('DAY',B.admit_dt,-1)

    /*re-admitted within 24 hours of discharge date*/

    WHERE A.conf_id B.conf_id

    AND A.src_sys_prov_id B.src_sys_prov_id

    /*transferred from different facility*/

    ;

    DELETE

    FROM PQI.&filename

    WHERE conf_ID IN

    (SELECT conf_id FROM &filename._TRANS)

    ;

    %mend transfer;

    USE MACRO VARIABLES FOR FREQUENTLY UPDATED/REFERENCED LISTS OF CODES

    For long lists of procedure and diagnosis codes with no electronic coding table (ECT) available, store them asmacro variables all in one place (the startup program) to make them easy to update as the specifications changeto include new codes.

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    7/9

    7

    %let markets =

    %str('WA','OR','CA','CO','TN','FL','SC','MD','DC','OH','NJ','NY','CT');

    /*eValue8 markets*/

    %let diabetes =

    %str('25000','25001','25002','25003','25010','25011','25012','25013','25020','2502

    1','25022','25023','25030','25050','25051','25052','25053','25060','25061','25062'

    ,'25063','25070','25071','25072','25073','25080','25031','25032','25033','25040','25041','25042','25043','25081','25082','25083','25090','25091','25092','25093');

    /*diabetes diagnosis codes, PQI 1,3,14,16*/

    For long lists of codes with an ECT available, use the SQL procedure to select into macro variables that are easyto reference in multiple places, eliminating the need to join to and select from the ECT more than once. When indevelopment, use system options SYMBOLGEN and MPRINT to check the log to make sure that the macro vari-ables resolve correctly.

    SELECT code

    INTO: opnaiprev separated by '","'

    /*outpatient, non-acute inpatient revenue proc codes*/

    FROM ref.ect

    WHERE description in('outpatient','nonacute_inpatient')

    AND typeofcode='RevCode'

    AND tablename='CDC_C'

    ;

    SELECT code

    INTO: aipedcpt separated by '","'/*acute inpatient, ed cpt proc codes*/

    FROM ref.ect

    WHERE description in('acute_inpatient','ed')

    AND typeofcode='CPT'

    AND tablename='CDC_C'

    /*ophthalmological services not needed for non-diabetic measures - 5,7,8,15*/

    ;

    Making use of macro variables makes the resulting code much shorter and easier to understand; instead of hav-

    ing the same long list of diagnosis codes repeated multiple times below, it is easier to see what the WHEREclause is actually doing without having to scroll:

    WHERE svc_dt BETWEEN "01jan&yearp"d AND "31dec&year"d

    /*current year or year prior*/

    AND (diag_cd1 IN (&diagcd) OR diag_cd2 IN (&diagcd) OR diag_cd3 IN

    (&diagcd))

    /*primary or secondary diagnosis code*/

    AND (proc_cd IN("&aipedcpt")

    /*acute inpatient or ED cpt codes*/

    OR (proc_cd IN("&aipedrev")

    /*3-byte rev codes for mco, 4-byte for ppo*/

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    8/9

    8

    Putting together the macro variables with the parameterized macros, the process of building denominators andnumerators to create the first measure looks like this:

    Instead of having to repeat blocks of nearly identical code, using parameterized macros for similar processesgreatly shortens the amount of code requiring maintenance.

    CONCLUSIONS

    Using simple techniques to organize process flow, macro variables to minimize hard coding, and parameterizedmacros along with even minimal documentation can greatly improve ease of code maintenance. This approachfacilitates code maintenance in three ways: by making portions of frequently updated code easier to locate (likehaving a good filing system), minimizing hard coding of dates and lists of codes, and by decreasing the overallvolume of code created in the first place.

    REFERENCES:

    SAS Institute Inc. 2009. SAS 9.2 Macro Language Reference. Cary, NC: SAS Institute, Inc.

    Patridge, C. Best Practices: Using SAS Effectively/Efficiently. HASUG presentation 2/24/2011.

    Rhodes, D. If You Have Programming Standards, Please Raise Your Hand: An Everymans Guide.http://www.nesug.org/Proceedings/nesug10/ma/ma10.pdf (5/31/2011).

    ACKNOWLEDGMENTS

    SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SASInstitute Inc. in the USA and other countries. indicates USA registration.

  • 8/4/2019 10 Steps to Easier SAS Code Maintenance

    9/9

    9

    CONTACT INFORMATION

    Your comments and questions are valued and encouraged. Contact the author at:

    Jessica Hampton

    CIGNA Corporation

    900 Cottage Grove Rd

    Bloomfield, CT 06002

    Work Phone: (860) 226-1938

    Email: [email protected]

    Web: http://www.linkedin.com/profile/view?id=40228999&locale=en_US&trk=tab_pro

    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *