Learn SAS for FREE Day11

OUTPUT DELIVERY SYSTEM (ODS)

ODS as the name suggests in just a system to deliver the output of our procedures to different systems like an excel file, HTML, word doc, pdf etc. Depending on our requirements we can modify the preferences and choose accordingly.

In the windowing environment, HTML output is enabled by default since SAS9.3

Prior to SAS 9.3, we had listing as default output.

To confirm, go to Tools > Options > Preferences from the menu at the top of the main SAS window.

Then click the Results tab.
As we find that in our latest SAS version 9.4 we have HTML as default output. ODS Graphics checkbox is also selecting which is basically for generating graphs by default. Further the HTMLBlue color is selected.
HTML output can be created on any environment, unix, windows etc except MAINFRAMES


SETTING ODS DESTINATION at RUN TIME

It is possible to change the destination to say listing, html, pdf etc at run time. We can even disable any or all of these destinations at run time.
Assume, HTML is the by default destination enabled and we have not changed any ods settings. In order to generate a pdf output, we can close HTML destination and enable pdf:
ODS HTML CLOSE;
ODS PDF FILE='c:\output\empdata.pdf';
PROC PRINT DATA=EMP;
RUN;
ODS PDF CLOSE;
In the above, we are closing HTML output first, then enabling PDF output by specifying the file name and location.  In the end it is mandatory to close pdf output, else the file will not be closed and created.
Please note that its not mandatory to close HTML destination, we can open several destinations and get same output in various formats.



HTML OUTPUT DESTINATION

In case we are only interested in HTML output, then we can create very neat looking HTML reports.
Using ODS statement, we will close all destinations (not mandatory) and open only HTML. The main benefit of closing other destinations, is that it saves system resources in case other destinations are open.
ODS  _ALL_  CLOSE;
This closes all destinations, similarly in case we only want to close LISTING:
ODS  LISTING CLOSE;
To re-enable listing output:
ODS  LISTING;
We don’t have to say “open” “enable” or anything. It assumes you want to open it.
To work with HTML destination, let us work with an emp dataset as below:
DATA EMP;
INPUT NAME $ AGE GENDER $ salary department $;
DATALINES;
sumit 35 M 1000 IT
jack 45 M 2000 IT
tina 27 F 5000 HR
julia 35 F 4000 IT
tim 35 M 4000 IT
sumit 56 M 5000 IT
;RUN;
Now, let us close all destinations and enable HTML.
ODS _ALL_ CLOSE;
ODS HTML FILE= 'c:\output\empdata.html';
PROC PRINT DATA=emp;
RUN;
 As we see it created a simple HTML report at our specified destination. As we selected HTMLBlue (default selection) the bars are blue in color.
What if we have more than one procedure to print?
ODS _ALL_ CLOSE;
ODS HTML FILE= 'c:\output\empdata.html'; 
 PROC PRINT DATA=emp; 
 PROC MEANS DATA=emp; 
RUN;

Here we are printing 2 procedures in the same html file:

 

Q) What if we don’t specify a location with HTML destination?

ODS _ALL_ CLOSE; 
ODS HTML; 
PROC PRINT DATA=emp;
PROC PRINT DATA=dept;  
RUN;

Ans: The above will create a single HTML file with output of both the above procedures.

HTML file will be located in the WORK directory by DEFAULT, unless path/file names are specified.

 

We can also create a fileref and then use it to create HTML file:

FILENAME myhtml "c:\data\emp.html”; 
ODS HTML BODY=myhtml;
:
:

Default style for HTML output is HTMLBlue, in case we need to make it banker (bold) style:

ODS HTML BODY=’c:\data\emp.html’      STYLE=banker;

STYLE=banker is without quotes.

 

We can specify a PATH, and not the file name, it will choose filename by itself:

ODS _ALL_ CLOSE; 
ODS HTML         PATH= 'C:\Output; 
PROC PRINT DATA=emp;
PROC PRINT DATA=dept;  
RUN;

Here we have specified “Path=”, that needs to be a directory, SAS will choose filename itself. If we specify a “File=”, then it needs to be a specific file name with path.

Running the above code we get:

This creates file “sashtml1.htm”. The next time we run it will be “sashtml2.htm” and so on…

But this has created one HTML file for both the procedures that we ran, in case we need a separate file for each procedure:

ODS _ALL_ CLOSE; 
ODS HTML     NEWFILE = PROC   PATH= 'C:\Output; 
 PROC PRINT DATA=emp;
 PROC PRINT DATA=dept;  
RUN;

Here we used “NEWFILE=PROC”, this tells ODS to create a new html file for each procedure input.

If we specify “NEWFILE=PROC” and also use FILE = filename option, say FILE = abcd.html, then if 3 procedures are being processed, we will have file names as:

abcd.html    abcd1.html    abcd2.html




CREATING FRAME IN HTML OUTPUT

The last output is pretty decent but its not something that is very presentable. Instead, we can create an HTML output, that contains a Frame, with body as above output. It will also have a “CONTENTS” block that lists all the procedures included in the output.

ODS HTML 
    FRAME    = 'c:\output\frame.html'
    CONTENTS = 'c:\output\contents.html'
    BODY     = 'c:\output\body.html'
 ;
PROC PRINT DATA=emp;
PROC MEANS DATA=emp; 
RUN;

This creates 3 files as shown below:

Lets open each of these files and check the details:

1. body.html

The above shows the body is just the results of the procedure which we submitted.

 

2. Contents:

 

3. Last we look at FRAME:

As we see the Frame is divided in to 2 parts, on left we are to see “contents.html” and to the right we to see “body.html”. If there are more procedures, then clicking on any of them in contents, will show the output of that in body part.

If we take these files and place them on our server, then body and contents will show the required data. But the Frame.html will not show any data, that is because the frame.html will be pointing to “C:\OUTPUT” path and not the path of our server to locate body and contents.

Either we modify the frame.html, which looks like below:

Suppose we want it to locate the contents.html and body.html from our server path, say “10.129.2.3/output” but still create these files in our local system at “c:/output/” then:

ODS HTML 
    FRAME    = 'c:\output\frame.html'
        (url = '10.129.2.3\output\frame.html')
    CONTENTS = 'c:\output\contents.html'
        (url = '10.129.2.3\output\contents.html')
    BODY     = 'c:\output\body.html'
       (url  = '10.129.2.3\output\body.html')
   ;
PROC PRINT DATA=emp;
PROC MEANS DATA=emp; 
RUN;

Here the files will be created locally at “c:\output\” folder but internally they will point to server path. Lets confirm this from frame.html:

The above is a very painful way of specifying server URL. A shortcut is as below:

ODS HTML 
   PATH    = 'c:\output\'   (URL='10.129.2.3\output\') 
   FRAME   = 'frame.html'
   CONTENTS= 'contents.html'
   BODY    = 'body.html'
 ;
PROC PRINT DATA=emp;
PROC MEANS DATA=emp; 
RUN;

 

Q) What is the purpose of the URL= suboptions?

Ans: To create relative link addresses for loading the files from a server.

 

Q) What is the purpose of the PATH= suboption?

ans:  It specifies the location of HTML file output.



LISTING OUTPUT

The listing output has been there almost since the beginning of SAS but nowadays, HTML, PDF, PPT, RTF and other such formats have taken over. But what is the listing output?

Well, as mentioned till SAS 9.2, Listing output was default, but since 9.3, we have HTML as default. Let us run a simple procedure to generate Listing output, assuming its not enabled.

ODS _ALL_ CLOSE;
ODS LISTING  FILE = 'c:\output\empfile.txt';
PROC PRINT DATA=mylib.emp;
RUN;
ODS LISTING CLOSE;

Running the above code we get:

When we check the location of file, we will see that empdata.txt has been created.

The output also shows the date and time to top right. Whereas the data is right in the center. Also, at the extreme right, we see page number as well.

In order to remove date and page number, we can specify:

OPTIONS NODATE NONUMBER ;

We can also specify that the data is not in center…

OPTIONS   NODATE     NONUMBER    NOCENTER;

In case we want to limit line and page size:

OPTIONS    pagesize=20   linesize= 50;

 

Please note that pagesize, linesize, nodate and nonumber only apply to listing output. Whereas NOCENTER also applies to HTML.

Let us run a procedure creating both HTML and Listing output, without any of above options.

ODS _ALL_ CLOSE;
ODS LISTING FILE = 'C:/lib/empfile.txt';
ODS HTML FILE = 'C:/lib/empfile.htm';
PROC PRINT DATA= emp;
RUN;
ODS _ALL_ CLOSE;

Let us check both HTML and Listing output:

 

As we see both the outputs are “Centered”. Now lets us remove date and page number from the listing output. Also, let us set the option of NOCENTERED.

ODS _ALL_ CLOSE;
ODS LISTING FILE = 'C:/lib/empfile.txt';
ODS HTML FILE = 'C:/lib/empfile.htm';
OPTIONS NODATE NONUMBER  NOCENTER;
PROC PRINT DATA= emp;
RUN;
ODS _ALL_ CLOSE;

Both the outputs are towards left side, whereas date and number of the page has been removed from listing.


Showing Sum of Numbers

Using PROC PRINT we can find sum of any variable etc. We shall work on this on Day#12.

Right now focus on what is seen the HTML and Listing:

ODS _ALL_ CLOSE;
ODS LISTING FILE = 'C:/lib/empfile.txt';
ODS HTML FILE = 'C:/lib/empfile.htm';
OPTIONS NODATE NONUMBER  NOCENTER;
PROC PRINT DATA= emp;
SUM salary;
RUN;
ODS _ALL_ CLOSE;

The HTML output as well shows the sum almost in a neat way.

If we take sum of some variable, but do not select that variable using VAR statement, then also that variable appears. consider below:
PROC PRINT DATA=test;
 VAR name age;
 SUM salary;
RUN;
The salary column is not selected but it appears, this happens in both html and listing.
Q)What if we used “Format Dollar9.” on salary in Proc Print. Does Sum also contain $ sign?
A) Yes, see below:


GETTING SUBTOTALS

data test;
input name $ age salary department $;
datalines;
sumit 35  1000 IT
jack  44  2500 HR
tim   22  5500 IT
eric  34  3500 HR
hulk  27  2000 IT
mak   48  4000 IT
;run;
 We want to sum salaries by department..
FIRST WE HAVE TO MANDATORY SORT DATA BY THE GROUPING VARIABLE
PROC SORT DATA=test
 BY department;
RUN;


ODS _ALL_ CLOSE; 
ODS LISTING FILE = 'C:/lib/empfile.txt'; 
ODS HTML FILE = 'C:/lib/empfile.htm'; 
OPTIONS NOCENTER; 
PROC PRINT;
  SUM salary;
  BY  department;
RUN;

The BY clause causes to group the data by that variable.

It shows sum for each department, and a final total sum at the end.

 

If we want each department details on separate pages:
PROC PRINT DATA=test;
 SUM salary;
 BY  department;
 PAGEBY  department;
RUN;
we can also put titles and footnotes by
TITLE<n> ‘text’;
FOOTNOTE<n> ‘text’;
n is a number from 1 to 10
The maximum title or footnote length depends on the value of the LINESIZE= option
PROC PRINT DATA=test;
 SUM salary;
 BY  department;
 PAGEBY  department;
   TITLE1 'SALARY DETAILS OF EACH DEPARTMENT';
   TITLE2 'TOTAL SALARY LISTED AT THE END';
   FOOTNOTE 'END OF REPORT';
RUN;
We can have title3 after title1. thats ok. but space of title2 will be left 
These options for Title and Footnotes, and Sum, BY etc are part of PROC PRINT and not Listing or HTML output.
We cover PROC PRINT indepth on coming day #12.
Posted in: SAS Filed under:

Leave a Reply

Your email address will not be published. Required fields are marked *