/********************************************************** ** mpcb_comp.sas * ** * ** Computes the Month Prenatal Care Began * ** * ** Written by Steve Steimel * ** 2007.03.28 * ** * ** PURPOSE: * ** This program calculates the Computed Month * ** Prenatal Care Begins(MPCB) using the Date of Last * ** Menses(DLMP), Date of First Prenatal Care(DFPC), * ** Date of Birth(DOB), Obstetric Gestation(OBGEST) * ** and/or Prenatal Care Visits(TPCV). This progam * ** is based on the Instruction Manual Part 12 * ** Version (8/31/05) Computer Edits for Natality * ** Data 2003 Revised Certificate Effective 2003 for * ** Revising States as well as subsequent emails * ** noting changes and adustments to the calculations.* ** * ** INPUT: * ** The input file is assumed to be in the format and * ** record length (916) of the 2003 Revision of the * ** State's file as it is sent to NCHS. The fields * ** anticipated positions follows, it is assumed that * ** the positions with asterics(*) are valid: * ** * ** STATE $ 5-6 CERT* $ 7-12 * ** VOID $ 13 DOB_YY* $ 1-4 * ** DOB_MM $ 31-32 DOB_DD $ 33-34 * ** DLMP_YY $ 812-815 DLMP_MM $ 816-817 * ** DLMP_DD $ 818-819 DFPC_YY $ 757-760 * ** DFPC_MM $ 753-754 DFPC_DD $ 755-756 * ** TPCV $ 769-770 OBGEST $ 870-871. * ** * ** OUTPUT: * ** Though script is included to output to a SAS * ** table or a printout, currently, the resulting * ** output will be a text file with a record length * ** of 20 in the following format: * ** * ** STATE $ 1-2 DOB_YY $ 4-7 * ** CERT $ 9-14 MPCB_COMP $16-17. * ** * ** SOFTWARE: * ** PC SAS 9.1.3 Service Pack 3 for XP Pro Platform. * ** * ** REQUIREMENTS: * ** The user should update the library name(LIBNAME), * ** the input filename(READIN) and the output * ** filename(PUTOUT) in the first few lines of the * ** script to work properly with their needs. If * ** printing the obs= will probably require adjusting.* ** * ** NOTES: * ** For consistency purposes, initial variable names * ** were taken from Jiquan Xu's Gestation Calculation * ** program. * ** * **********************************************************/ libname MPCBLIB 'H:\SAS\work'; * FILENAME READIN 'H:\work\fl05950a.nat'; * FILENAME PUTOUT 'H:\work\fl05950a.npc'; * FILENAME READIN 'H:\work\id05972a.nat'; * FILENAME PUTOUT 'H:\work\id05972a.npc'; * FILENAME READIN 'H:\work\ks05950a.nat'; * FILENAME PUTOUT 'H:\work\ks05950a.npc'; * FILENAME READIN 'H:\work\ky05939a.nat'; * FILENAME PUTOUT 'H:\work\ky05939a.npc'; FILENAME READIN 'H:\work\ne05917a.nat'; FILENAME PUTOUT 'H:\work\ne05917a.npc'; * FILENAME READIN 'H:\work\nh05911a.nat'; * FILENAME PUTOUT 'H:\work\nh05911a.npc'; * FILENAME READIN 'H:\work\ny05979a.nat'; * FILENAME PUTOUT 'H:\work\ny05979a.npc'; * FILENAME READIN 'H:\work\pa05919a.nat'; * FILENAME PUTOUT 'H:\work\pa05919a.npc'; * FILENAME READIN 'H:\work\sc05936a.nat'; * FILENAME PUTOUT 'H:\work\sc05936a.npc'; * FILENAME READIN 'H:\work\tn05977a.nat'; * FILENAME PUTOUT 'H:\work\tn05977a.npc'; * FILENAME READIN 'H:\work\tx05962a.nat'; * FILENAME PUTOUT 'H:\work\tx05962a.npc'; * FILENAME READIN 'H:\work\vt05904a.nat'; * FILENAME PUTOUT 'H:\work\vt05904a.npc'; * FILENAME READIN 'H:\work\wa05942a.nat'; * FILENAME PUTOUT 'H:\work\wa05942a.npc'; * FILENAME READIN 'H:\work\pr05923a.nat'; * FILENAME PUTOUT 'H:\work\pr05923a.npc'; options obs=5000000; %macro CENTDAY(yymmdd,centdays); leap = 0; * convert to integers; yy = int(&yymmdd/10000); mm = int(mod(&yymmdd,10000)/100); dd = int(&yymmdd) - int(&yymmdd/100)*100; * convert 1st of month to mdays; if mm = 1 then mdays = 0; else if mm = 2 then mdays = 31; else if mm = 3 then mdays = 59; else if mm = 4 then mdays = 90; else if mm = 5 then mdays = 120; else if mm = 6 then mdays = 151; else if mm = 7 then mdays = 181; else if mm = 8 then mdays = 212; else if mm = 9 then mdays = 243; else if mm = 10 then mdays = 273; else if mm = 11 then mdays = 304; else if mm = 12 then mdays = 334; else if mm = 88 then mdays = 999999; else if mm = 99 then mdays = 999999; * determine if leap day is necessary; if mdays < 999999 then do; if yy = 8888 then mdays = 999999; else if yy = 9999 then mdays = 999999; else if mod(yy,4) = 0 & mm > 2 then do; leap = 1; end; end; * century days = ((yy*365) + mdays + dd + leap); if mdays < 999999 then do; ¢days = (yy * 365) + mdays + dd + leap; end; * put &yymmdd yy mm dd days; %mend CENTDAY; DATA S01_READ; * read in data from text file; INFILE READIN lrecl = 916 MISSOVER; INPUT STATE $ 5-6 CERT $ 7-12 VOID $ 13 DOB_YY $ 1-4 DOB_MM $ 31-32 DOB_DD $ 33-34 DLMP_YY $ 812-815 DLMP_MM $ 816-817 DLMP_DD $ 818-819 DFPC_YY $ 757-760 DFPC_MM $ 753-754 DFPC_DD $ 755-756 TPCV $ 769-770 OBGEST $ 870-871 ; * remove voids; IF VOID = '1' THEN DELETE; * delete the record with void value 1; RUN; DATA S02_WORK (KEEP = STATE CERT iDOB_YY iDOB_MM iDOB_DD iLMP_YY iLMP_MM iLMP_DD iFPC_YY iFPC_MM iFPC_DD DOB_YY DOB_MM DOB_DD DOB DLMP_YY DLMP_MM DLMP_DD DLMP DFPC_YY DFPC_MM DFPC_DD DFPC OBGEST TPCV DDIF MDIF CENT_DFPC CENT_DLMP CENT_DOB CENT_OE method); set S01_READ; * setup array for day of DFPC_DD imputation; ARRAY imp_dd{12} $m1-m12; RETAIN imp_dd ('01','01','01','01','01','01','01','01','01','01','01','01'); * populate input buffer; iDOB_YY = DOB_YY; * date of birth year; iDOB_MM = DOB_MM; * date of birth month; iDOB_DD = DOB_DD; * date of birth day; iLMP_YY = DLMP_YY; * last menses year; iLMP_MM = DLMP_MM; * last menses month; iLMP_DD = DLMP_DD; * last menses day; iFPC_YY = DFPC_YY; * first prenatal care year; iFPC_MM = DFPC_MM; * first prenatal care month; iFPC_DD = DFPC_DD; * first prenatal care day; * initialize variables; CENT_DLMP = 0; * century days DLMP; CENT_DFPC = 0; * century days DFPC; CENT_DOB = 0; * century days DOB; CENT_OE = 0; * century days Obstetric Estimate; DDIF = 0; * difference in days; MDIF = 0; * difference in months; METHOD = '-'; * method used in calculation; * Validate DOB; * Check DOB_MM; if DOB_MM < '01' | DOB_MM > '12' then do; DOB_MM = lag(DOB_MM); if DOB_MM = . then DOB_MM = '01'; end; * Check DOB_DD; if DOB_DD < '01' | DOB_DD > '31' then do; DOB_DD = '15'; end; if DOB_MM = '02' then do; *if DOB_MM = '02' then do; * Check for leap year; if MOD(INPUT(SUBSTR(DOB_YY, 3), 2.), 4) = 0 then do; if DOB_DD > '29' then DOB_DD = '29'; * leap year; end; else do; if DOB_DD > '28' then DOB_DD = '28'; * std year; end; *end; end; if DOB_MM in('04','06','09','11') then do; if DOB_DD > '30' then DOB_DD = '30'; end; * Create DOB string; DOB = DOB_YY || DOB_MM || DOB_DD; * Validate DLMP; * check DLMP_MM; if DLMP_MM < '01' | DLMP_MM > '12' then do; DLMP_MM = '99'; end; * check DLMP_DD; if DLMP_DD < '01' | DLMP_DD > '31' then do; DLMP_DD = '99'; end; if DLMP_MM <= '12' & DLMP_DD <= '31' then do; if DLMP_MM = '02' & DLMP_DD <= '31' then do; if DLMP_MM = '02' then do; * Check for Leap Year; if MOD(INPUT(SUBSTR(DLMP_YY, 3), 2.), 4) = 0 then do; if DLMP_DD > '29' then DLMP_DD = '29'; * leap year; end; else do; if DLMP_DD > '28' then DLMP_DD = '28'; * std year; end; end; end; else if DLMP_MM in('04','06','09','11') & DLMP_DD <= '31' then do; if DLMP_DD > '30' then DLMP_DD = '30'; end; end; * check DLMP_YY; if DLMP_YY > DOB_YY | DLMP_YY < DOB_YY-2 then do; DLMP_YY = '9999'; end; * Create DLMP string; DLMP = DLMP_YY || DLMP_MM || DLMP_DD; * Validate DFPC; * work DFPC_MM; if DFPC_MM not in ('01','02','03','04','05', '06','07','08','09','10', '11','12','88','99') then do; DFPC_MM = '99'; end; * Check DFPC_YY; if DFPC_YY > DOB_YY & DFPC_YY ^= '8888' then do; DFPC_YY = '9999'; end; if DFPC_YY = '9999' & DFPC_MM < '99' then do; if DFPC_MM > DOB_MM then do; DFPC_YY = DOB_YY - 1; end; if DFPC_MM <= DOB_MM then do; DFPC_YY = DOB_YY; end; end; if DFPC_YY < DOB_YY - 2 then do; DFPC_YY = '9999'; end; * Check DFPC_DD; if (DFPC_DD < '01' | DFPC_DD > '31') & DFPC_DD not in ('88','99') then do; DFPC_DD = '99'; end; if DFPC_MM <= '12' & DFPC_DD <= '31' then do; if DFPC_MM = '02' & DFPC_DD <= '31' then do; if DFPC_MM = '02' then do; * Check for Leap Year; if MOD(INPUT(SUBSTR(DFPC_YY, 3), 2.), 4) = 0 then do; if DFPC_DD > '29' then DFPC_DD = '29'; * leap year; end; else do; if DFPC_DD > '28' then DFPC_DD = '28'; * std year; end; end; end; else if DFPC_MM in('04','06','09','11') & DFPC_DD <= '31' then do; if DFPC_DD > '30' then DFPC_DD = '30'; end; * update hotdeck with valid value; imp_dd(DFPC_MM) = DFPC_DD; end; if DFPC_DD = '99' & DFPC_MM not in ('99','88') then do; * read hotdeck to get valid value; DFPC_DD = imp_dd(DFPC_MM); end; * Create DFPC string; DFPC = DFPC_YY || DFPC_MM || DFPC_DD; * Display imputation matrix from hotdeck; * put CERT imp_dd(1) imp_dd(2) imp_dd(3) imp_dd(4) imp_dd(5) imp_dd(6) imp_dd(7) imp_dd(8) imp_dd(9) imp_dd(10) imp_dd(11) imp_dd(12); * Compare DFPC & DOB strings for consistency; if (DFPC>=DOB & DFPC<'88888888' & DLMP_YY^='8888' & DLMP_YY^='9999') then do; DFPC_YY = '9999'; DFPC_MM = '99'; DFPC_DD = '99'; * Restring DFPC with changes; DFPC = DFPC_YY || DFPC_MM || DFPC_DD; end; if DLMP_MM = '99' then MDIF = 99; if DLMP_YY = '9999' then MDIF = 99; * Calculate Century Dates; %CENTDAY(DFPC, CENT_DFPC); if(DLMP_YY^='9999' & DLMP_MM^='99' & DLMP_DD^='99') then do; %CENTDAY(DLMP, CENT_DLMP); end; else do; %CENTDAY(DOB, CENT_DOB); end; * Calculate MPCB_COMP; * Method 1 - No Prenatal Care; if (DFPC_MM = "88" | DFPC_YY = "8888") then do; MDIF = 88; METHOD = '1'; end; * Method 2 - Not Stated DFPC_MM; else if (DFPC_MM = "99") then do; MDIF = 99; METHOD = '2'; end; * Method D - Date Calculation; else if 700000 < CENT_DLMP < 999999 & 700000 < CENT_DFPC < 999999 then do; * adjust for multi-year leap differences; if (mod(DLMP_YY,4)=0 & DLMP_YY^=DFPC_YY) then do; CENT_DFPC = CENT_DFPC + 1; end; * calculate MDIF; METHOD = 'D'; DDIF = CENT_DFPC - CENT_DLMP; MDIF = INT(DDIF/30.4) + 1; end; * Method G - Calculation using Obstetric Gestation; else do; METHOD = 'G'; if CENT_DLMP = 999999 then MDIF = 0; else do; if (OBGEST = '99') then do; MDIF = 99; end; else do; * Calculate by using gestation; CENT_OE = CENT_DOB - (OBGEST * 7); DDIF = CENT_DFPC - CENT_OE; MDIF = INT(DDIF/30.4) + 1; end; end; end; * Check MDIF for extreme values; if DFPC_YY = '9999' then MDIF = 99; if TPCV = '00' then MDIF = 88; if MDIF < 88 then do; if MDIF <= 0 then MDIF = 1; if MDIF > 10 then MDIF = 10; end; RUN; * Create file; DATA _NULL_; SET S02_WORK; FILE putout lrecl=20; PUT @1 STATE $2. @4 DOB_YY $4. @9 CERT $6. @16 MDIF 2. ; RUN; * Other Output Options: * Create SAS Table; /* DATA S03_MPCB (KEEP=STATE DOB_YY CERT MDIF); SET S02_WORK; RUN; */ * Print Output to Screen; /* PROC PRINT data=S02_WORK (obs=100); VAR STATE DOB_YY CERT MDIF ; RUN; */