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/