5 SAS Logs

SAS is unusual software in that it generates two distinct output streams. In addition to the typical tables and graphs (in a variety of formats, including text and html), SAS echos your code and writes notes and messages in a separate log file. Most software directs all of this into just one document.

From time to time it is useful to show the reader what they will find in a log file. How do we get knitr to include that?

There are several approaches we could take here, depending on just what we need to show the reader. If we would like to show the log in place of the code (since it echos the code...), we can use the saslog engine.

5.1 Set up

Set up your document.

library(SASmarkdown)

5.2 Using the saslog engine

To show the reader the log in place of a code block, use the saslog engine.

```{saslog} 
proc means data=sashelp.class;
run;
```

In your final document this looks like:

2          proc means data=sashelp.class;
3          run;

NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The PROCEDURE MEANS printed page 1.
NOTE: PROCEDURE MEANS used (Total process time):
      real time           0.03 seconds
      cpu time            0.03 seconds
      
                            The MEANS Procedure

 Variable    N           Mean        Std Dev        Minimum        Maximum
 -------------------------------------------------------------------------
 Age        19     13.3157895      1.4926722     11.0000000     16.0000000
 Height     19     62.3368421      5.1270752     51.3000000     72.0000000
 Weight     19    100.0263158     22.7739335     50.5000000    150.0000000
 -------------------------------------------------------------------------

Cleaning up and making the log more readable is the topic of the next chapter.

5.3 Using the sashtmllog and sashtml5log engines

We can have similar results with HTML output.

```{sashtmllog} 
proc means data=sashelp.class;
run;
```

In your final document this looks like:

6          proc means data=sashelp.class;
7          run;

NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: PROCEDURE MEANS used (Total process time):
      real time           1.67 seconds
      cpu time            0.00 seconds
      
Variable N Mean Std Dev Minimum Maximum
Age
Height
Weight
19
19
19
13.3157895
62.3368421
100.0263158
1.4926722
5.1270752
22.7739335
11.0000000
51.3000000
50.5000000
16.0000000
72.0000000
150.0000000

5.4 SAS ERROR messages

SAS does not always exit with an error when it encounters problems, but when it does, you should see the log in your document instead of the code.

5.4.1 Semantic and Execution Errors

Semantic errors (typos etc.) and execution errors (e.g. the data set you call does not exist) cause SAS to return an error status when SAS finishes. This will automatically cause SASmarkdown to switch from the sas engine to the saslog engine.

In this example, trying to use WORK data without any data set there, SAS produces an ERROR, and no output is produced.)

```{sas procerror} 
proc means data=cars;
run;
```

Which produces:

2          proc means data=cars;
ERROR: File WORK.CARS.DATA does not exist.
3          run;

NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE MEANS used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

ERROR: Errors printed on page 1.

5.4.2 Mathematical Errors

Division by zero produces error flags within the DATA step, but does not cause SAS to return an error code when it finishes. The sas engine gives us the usual output.

To see the DATA step ERROR, explicitly switch to the saslog engine.

```{saslog divzero} 
data class;
  set sashelp.class(obs=5);
  age0 = age/0;
  keep age age0;
  run;

proc print data=class;
run;
```

which produces both the log and the PROC PRINT output.

2          data class;
3              set sashelp.class(obs=5);
4              age0 = age/0;
5              keep age age0;
6              run;

NOTE: Division by zero detected at line 4 column 15.
Name=Alfred Sex=M Age=14 Height=69 Weight=112.5 age0=. _ERROR_=1 _N_=1
NOTE: Division by zero detected at line 4 column 15.
Name=Alice Sex=F Age=13 Height=56.5 Weight=84 age0=. _ERROR_=1 _N_=2
NOTE: Division by zero detected at line 4 column 15.
Name=Barbara Sex=F Age=13 Height=65.3 Weight=98 age0=. _ERROR_=1 _N_=3
NOTE: Division by zero detected at line 4 column 15.
Name=Carol Sex=F Age=14 Height=62.8 Weight=102.5 age0=. _ERROR_=1 _N_=4
NOTE: Division by zero detected at line 4 column 15.
Name=Henry Sex=M Age=14 Height=63.5 Weight=102.5 age0=. _ERROR_=1 _N_=5
NOTE: Mathematical operations could not be performed at the following 
      places. The results of the operations have been set to missing 
      values.
      Each place is given by: (Number of times) at (Line):(Column).
      5 at 4:15   
NOTE: There were 5 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.CLASS has 5 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

7          
8          proc print data=class;
9          run;

NOTE: There were 5 observations read from the data set WORK.CLASS.
NOTE: The PROCEDURE PRINT printed page 1.
NOTE: PROCEDURE PRINT used (Total process time):
      real time           0.03 seconds
      cpu time            0.01 seconds
      
                            Obs    Age    age0

                             1      14      . 
                             2      13      . 
                             3      13      . 
                             4      14      . 
                             5      14      . 

The same results are produced with the html and htmllog or the html5 and html5log engines.

Written using

  • SASmarkdown version 0.8.0.
  • knitr version 1.40.
  • R version 4.2.2 (2022-10-31 ucrt).