Cleaning Up SAS Log Output

Doug Hemken

Jul 2017

If you are using the saslog or sashtmllog engines, or if you are allowing SAS semantic errors to appear in your document, you may not want to show the entire log file. To gain some control over what shows up in your document, you can use "saslog_hookset".

The usual SAS set up is needed, as in other vignettes, and is not shown here.

A Source Hook for the "saslog" Engine

With the saslog or sashtmllog engines we use the "saslog_hookset" function, specifying
a source hook. This creates a number of chunk options we can use to filter the SAS log.

Hook Specification

(This is a "source" hook, because we are showing the SAS log where we usually show the SAS code, the "source".)

require(SASmarkdown) # if not invoked previously
saslog_hookset("source")

Hook Use

First, we setup some code using "engine='sas'". We will repeatedly use the same code by repeating the chunk label.

proc means data=sashelp.class(keep=height);
run;
                            The MEANS Procedure

                        Analysis Variable : Height 
 
     N            Mean         Std Dev         Minimum         Maximum
    ------------------------------------------------------------------
    19      62.3368421       5.1270752      51.3000000      72.0000000
    ------------------------------------------------------------------

If we switch to engine saslog

```{r procmeans2, engine='saslog'}
```

we don’t get ALL of the SAS log file, but we may be showing more information than we really want to present to the reader.

2          proc means data=sashelp.class(keep=height);
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.09 seconds
      cpu time            0.06 seconds
      
                            The MEANS Procedure

                        Analysis Variable : Height 
 
     N            Mean         Std Dev         Minimum         Maximum
    ------------------------------------------------------------------
    19      62.3368421       5.1270752      51.3000000      72.0000000
    ------------------------------------------------------------------

We can filter the log to suppress processing times by using chunk option "SASproctime=FALSE".

```{r procmeans2, engine='saslog', SASproctime=FALSE, results='hide'}
```
2          proc means data=sashelp.class(keep=height);
3          run;

NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The PROCEDURE MEANS printed page 1.
      

Other filtering options include no SAS command echo with "SASecho=FALSE" and no SAS NOTES with "SASnotes=FALSE".

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.10 seconds
      cpu time            0.10 seconds
      
2          proc means data=sashelp.class(keep=height);
3          run;

      real time           0.10 seconds
      cpu time            0.11 seconds
      

Interactions (or Lack Thereof)

Chunks in other languages are unaffected (for example, R).

runif(5)
[1] 0.8543188 0.7718499 0.7847809 0.3490489 0.3275551

And the sas and sashtml engines are unaffected, as seen in our intial code chunk and here:

proc means data=sashelp.class(keep=height);
run;
Analysis Variable : Height
N Mean Std Dev Minimum Maximum
19 62.3368421 5.1270752 51.3000000 72.0000000

An Output Hook for PROC PRINTTO

These same filters can be used as "output" hooks.

Suppose you wanted to process SAS log files separately. You could use SAS's PROC PRINTTO to save the log files, and read them into your document using R commands.

(For this vignette we reset the "source" hook, from above. In general you will NOT need to reset, you will use one or the other.)

knitr::knit_hooks$set(source=hook_orig) # just for this example

saslog_hookset("output")

In this example I am using the PROC PRINTTO method of capturing the log.

Note that all output is run through the output hook, but our alterations are specific to the SAS log None of the text we are filtering appears in ordinary SAS or R output, so SAS output is untouched.

proc printto log="saslog.log" new;
proc means data=sashelp.class(keep=weight);
run;
                            The MEANS Procedure

                        Analysis Variable : Weight 
 
     N            Mean         Std Dev         Minimum         Maximum
    ------------------------------------------------------------------
    19     100.0263158      22.7739335      50.5000000     150.0000000
    ------------------------------------------------------------------

The log is then processed when it is shown by a separate code chunk (using R commands, not SAS).

```{r readlog}
cat(readLines("saslog.log"), sep="\n")
```
cat(readLines("saslog.log"), sep="\n")
NOTE: PROCEDURE PRINTTO used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

3          proc means data=sashelp.class(keep=weight);
4          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.09 seconds
      cpu time            0.07 seconds
      

We can now use the same chunk options as before.
No processing times, SASproctime=FALSE.

3          proc means data=sashelp.class(keep=weight);
4          run;

NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The PROCEDURE MEANS printed page 1.
      

No SAS command echo, SASecho=FALSE.

NOTE: PROCEDURE PRINTTO used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      


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.09 seconds
      cpu time            0.07 seconds
      

No SAS NOTES, SASnotes=FALSE.

      real time           0.00 seconds
      cpu time            0.00 seconds
      

3          proc means data=sashelp.class(keep=weight);
4          run;

      real time           0.09 seconds
      cpu time            0.07 seconds
      

Clean up is necessary in a final R chunk - this is NOT automated.

# Do not forget to remove the log file when you are done!
unlink("saslog.log")