What’s wrong NOW?! An introduction to debugging SAS programs for beginners Martha Cox Cancer Outcomes Research Program CDHA / Dalhousie What’s wrong NOW?! Types of Bugs Bug Droppings Bug Repellant Bug Killing – General Approach Bug Killing – Specific Bugs Types of Bugs Syntax / Semantic Types of Bugs Syntax / Semantic Execution-Time Types of Bugs Syntax / Semantic Execution-Time Data Types of Bugs Syntax / Semantic Execution-Time Data Logic Bug Droppings ERROR WARNING NOTE no messages Bug Repellant 1. Make your program easy to read Indent – within a step or a DO block One Semicolon per Line (or less!) Every step gets a RUN Every PROC gets a DATA= Comments, comments, comments Make your program easy to read data hyst; set hospital(keep=year pcode1-pcode10); array pcodes{*} pcode1-pcode10; length code $3 year 3; do i = 1 to 10; if pcodes{i}=:'689‘ then do; code = substr(pcodes{i},1,3); output; end; end; keep year code; title1 'Number of Selected Hysterectomy Procedures by Year'; proc freq noprint; tables year*code/list out=temp; run; /* Create a data set containing hysterectomy codes. */ data hyst; set hospital (keep=year pcode1-pcode10); array pcodes{*} pcode1-pcode10; length code $3 year 3 ; do i = 1 to 10; if pcodes{i} =: '689‘ then do; code = substr(pcodes{i},1,3); output; end; ** if **; end; ** do i **; keep year code; run; title1 'Number of Selected Hysterectomy Procedures by Year'; proc freq data=hyst noprint; tables year*code/list out=temp; run; Bug Repellant Make your program easy to read 2. Don’t destroy your data 1. Don’t Destroy Your Data: access=readonly libname survey 'C:\My Documents\Survey\' access=readonly; libname indata 'C:\Thesis\Data\' access=readonly; libname outdata 'C:\Thesis\Data\' ; Don’t Destroy Your Data: Use OUT= on PROC SORT proc sort data=thesis.hospital (keep=patient addate); by patient; run; proc sort data=thesis.hospital (keep=patient addate) out=patlist ; by patient; run; Don’t Destroy Your Data: options DATASTMTCHK= 7 8 9 10 11 options datastmtchk=none; data adults set survey.adult; if age > 65; run; NOTE: Variable age is uninitialized. NOTE: The SAS System stopped processing this step because of errors. WARNING: The data set WORK.ADULTS may be incomplete. When this step was stopped there were 0 observations and 1 variables. Don’t Destroy Your Data: options DATASTMTCHK= 12 options datastmtchk=corekeywords; 13 data adults NOTE: SCL source line. 14 set survey.adult; --56 ERROR 56-185: SET is not allowed in the DATA statement when option DATASTMTCHK=COREKEYWORDS. Check for a missing semicolon in the DATA statement, or use DATASTMTCHK=NONE. 15 16 if age > 65; run; Don’t Destroy Your Data: options MERGENOBY= 13 14 15 18 19 20 data valid not_valid; merge TEST_DATA(keep=ID in=a) master.master02(in=b); if a and b then output valid; else if not b then output not_valid; run; NOTE: There were 899 observations read from the data set TEST_DATA. NOTE: There were 1138309 observations read from the data set MASTER.MASTER02. NOTE: The data set WORK.VALID has 899 observations and 9 variables. NOTE: The data set WORK.NOT_VALID has 0 observations and 9 variables. Don’t Destroy Your Data: options MERGENOBY= 12 13 14 16 17 18 19 options mergenoby=error; data valid not_valid; merge TEST_DATA(keep=ID in=a) master.master02(in=b); if a and b then output valid; else if not b then output not_valid; run; +ERROR: No BY statement was specified for a MERGE statement. NOTE: The SAS System stopped processing this step because of errors. Bug Repellant Make your program (& your log) easy to read 2. Don’t destroy your data 3. Know your data 1. Know your data 21 22 23 24 data males; set survey.adult; if gender = 'M'; run; NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column). 23:12 NOTE: Invalid numeric data, 'M' , at line 23 column 12. Bug Repellant Make your program (& your log) easy to read 2. Don’t destroy your data 3. Know your data 4. Do a syntax check 1. Do a syntax check options OBS=0 NOREPLACE; Bug Repellant Make your program (& your log) easy to read 2. Don’t destroy your data 3. Know your data 4. Do a syntax check 1. Bug Killing 1. Read the LOG! Bug Killing 2. Start at the top & deal with one mess at a time. Bug Killing 2. Start at the top & deal with one mess at a time. • Use interactive SAS, if possible Bug Killing 2. Start at the top & deal with one mess at a time. • • Use interactive SAS, if possible Using ENDSAS Using ENDSAS < lots of SAS statements > proc freq data=workhrs; tables hrs / nofreq nocum norow; run; endsas; < lots more SAS statements > Bug Killing 2. Start at the top & deal with one mess at a time. • • • Use interactive SAS, if possible Using ENDSAS Using OPTIONS ERRORABEND Using ERRORABEND 1 options errorabend; 5 /* Number of Hours Worked Per Week */ 6 data workhrs(drop=b151); 7 set survey.newadult 8 (keep=wrk); ERROR: The variable wrk in the DROP, KEEP, or RENAME list has never been referenced. 9 length hrs 8; 10 hrs = input(b151, 8.); 11 run; ERROR: SAS ended due to errors. You specified: OPTIONS ERRORABEND;. Bug Killing 3. Look for horses, not zebras. Bug Killing Read the LOG! 2. Start at the top & deal with one mess at a time. 3. Look for horses, not zebras. 1. Bug Killing Some Specific Bugs WARNING or ERROR: misspelled keywords 33 data adult; NOTE: SCL source line. 34 st aborig.newadult; -1 WARNING 1-322: Assuming the symbol SET was misspelled as st. 35 run; ERROR: Invalid option name, parameter, or statement. Possible Causes: missing semicolon misspelled keyword unmatched quotation mark unclosed comment a DATA step statement in a PROC step a valid option used in the wrong place ERROR: Invalid option name, parameter, or statement. 3 data males(rop=gender); --22 ERROR 22-7: Invalid option name ROP. 4 5 6 set survey.adult; if gender = 2; run; NOTE: The SAS System stopped processing this step because of errors. ERROR: Invalid option name, parameter, or statement. 8 proc print data=survey.adult; NOTE: SCL source line. 9 set gender; --180 ERROR 180-322: Statement is not valid or it is used out of proper order. 10 run; NOTE: The SAS System stopped processing this step because of errors. ERROR: Invalid option name, parameter, or statement. 11 proc print data=survey.adult NOTE: SCL source line. 12 var gender; --- -22 202 ERROR 22-322: Syntax error, expecting one of the following: ;, (, DATA, DOUBLE, HEADING, LABEL, N, NOOBS, OBS, ROUND, ROWS, SPLIT, STYLE, UNIFORM, WIDTH. ERROR 202-322: The option or parameter is not recognized and will be ignored. 13 run; NOTE: The SAS System stopped processing this step because of errors. ERROR: Invalid option name, parameter, or statement. 14 * Print a list of Adult ages. 15 proc print data=survey.newadult; NOTE: SCL source line. 16 var b4; --180 ERROR 180-322: Statement is not valid or it is used out of proper order. 17 run; WARNING: unbalanced quotes 90 proc print data=hospital(obs=10); 91 title1 "Sample of Hospital Data; 92 run; 93 < more SAS statements > 91 title1 "Sample of Hospital Data; + _____________________ + _____________________ + _____________________ 32 + 32 + 32 WARNING 32-169: The quoted string currently being processed has become more than 262 characters long. You may have unbalanced quotation marks. NOTE: Missing values generated. 48 49 50 51 52 53 54 55 56 data test; a = 2; b = 4; c = .; x = a + b + c; y = sum(a,b,c); a = .; b = .; z = sum(a,b,c); z2 = sum(a,b,c,0); put x= y= z= z2= ; run; x=. y=6 z=. z2=0 NOTE: Missing values were generated as a result of performing an operation on missing values. Each place is given by: (Number of times) at (Line):(Column). 1 at 50:13 1 at 53:7 NOTE: Numeric to character conversion (or vice versa) 109 110 111 112 113 114 data adult2; length sexage $5 household 8 ; set adult; sexage = sex || age ; household = sum(kids, adults, 1); run; NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column). 112:19 NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column). 113:19 NOTE: Numeric to character conversion (or vice versa) 122 123 124 125 126 127 128 data adult3; length sexage $5 household 8 ; set adult; sexage = sex || put(age, 3. -L); kidsnum = input(kids, 8.); household = sum(kidsnum, adults, 1); run; NOTE: There were 493 observations read from the data set WORK.ADULT. NOTE: The data set WORK.ADULT3 has 493 observations and 8 variables. NOTE: Variable is uninitialized. Possible Causes: misspelling the variable name using a variable that was dropped in a previous step using the wrong data set using a variable before it is created NOTE: Variable is uninitialized. 140 141 142 143 144 data males; set survey.adult (keep=id community); if gender=2; run; NOTE: Variable gender is uninitialized. NOTE: There were 493 observations read from the data set SURVEY.ADULT. NOTE: The data set WORK.MALES has 0 observations and 3 variables. No Messages: Character values are being truncated. data groups; set survey.adult; if age < 20 then AgeGroup = 'Teen'; else if age > 65 then AgeGroup = 'Senior'; else AgeGroup = 'Adult'; run; proc freq data=groups; tables agegroup / nocum; run; No Messages: Character values are being truncated. The FREQ Procedure Age Group Frequency Percent -----------------------------Adul 388 78.70 Seni 17 3.45 Teen 88 17.85 No Messages: Character values are being truncated. data groups; set survey.adult; attrib AgeGroup length=$6 label='Age Group'; if age < 20 then AgeGroup = 'Teen'; else if age > 65 then AgeGroup = 'Senior'; else AgeGroup = 'Adult'; run; proc freq data=groups; tables agegroup / nocum; run; No Messages: Character values are being truncated. The FREQ Procedure Age Group Frequency Percent ------------------------------Adult 388 78.70 Senior 17 3.45 Teen 88 17.85 Questions? References Delwiche, Lora D., and Susan J. Slaughter, The Little SAS Book: a primer, Third Edition, SAS Institute, Cary, NC, 2003 Staum, Roger, To Err is Human; to Debug Divine, NESUG 15 Conference Proceedings Howard, Neil, How SAS Thinks, or Why the DATA Step Does What It Does, SUGI 29 Conference Proceedings Knapp, Peter, Debugging 101, NESUG 15 Conference Proceedings Rhodes, Dianne Louise, So You Want to Write a SUGI Paper? That Paper About Writing a Paper, SUGI 29 Conference Proceedings Resources Online documentation http://v9doc.sas.com/sasdoc/ Online conference proceedings – SUGI: http://support.sas.com/usergroups/ sugi/proceedings/index.html – NESUG: http://www.nesug.org/