How to find out what's new in SAS 9.4 maintenance

Today SAS began shipping the second maintenance release of SAS 9.4, colloquially known as "SAS 9.4M2". This is an incremental release, meant to build upon the already-solid SAS 9.4 platform. Even as a SAS insider, I cannot possibly keep track of every new feature that has been added in maintenance. But since I'm always on the hunt for interesting things to blog about, I find myself scanning the "What's New in SAS 9.4" document.

If you're coming from SAS 9.3 or earlier, then the entire "What's New" document is of interest to you. But if you're already using SAS 9.4 or even SAS 9.4 Maintenance 1, then you might be looking for the "9.4M2 Cliffs Notes". I'm afraid that the What's New document isn't structured that way -- it's organized by product and feature sets, and not chronologically by maintenance releases.

Fortunately, the document does call out the new features that have been added in each maintenance within the context of each product, and I've found a technique that helps me to find the highlights for M2. Here's what I do.

1. Visit the What's New section of From here, I click on What's New in SAS 9.4 (HTML version).

2. From the Contents section, select the product of interest. For example, I'm very interested in Base SAS. Each release brings new statements, functions, ODS enhancements, and new statistical graphics -- all under the huge umbrella of "Base".

3. Use the browser "Find" feature to locate the word "second". The writers and editors at SAS are very consistent with their terminology standards, and that's a big help for me here. I know that in this What's New document, I can find the newest features by locating what's called out for "the second maintenance release for SAS 9.4". Simply searching for "second" helps me to find these.

For example, I learned that SAS 9.4 offers enhancements to the new ODS EPUB and ODS HTML5 destinations. I'm interested in those because David Kelley demonstrated them at SAS Global Forum 2014.

The What's New in SAS 9.4 document contains only the highlights, but provides links to the documentation with more details. For example, the mention about the ODS HTML5 enhancements links to the SAS 9.4 Output Delivery System: User's Guide, which contains a more detailed view of what's new in ODS. From there, I can use the same browser trick to find mentions of "second" to see what was added to ODS in SAS 9.4M2.

The analytical products (such as SAS/STAT, SAS/IML, and SAS Enterprise Miner) make this a little bit easier by issuing new version numbers. The SAS 9.4M2 release of SAS/STAT is versioned as 13.2, and those new features are discussed in the SAS/STAT 13.2 section of the SAS 9.4 What's New document, with more details in the SAS/STAT documentation.

Post a Comment

More SAS tips coming to your inbox

When it comes to e-mail-based newsletters, I'm of two minds. On one hand, I feel like I receive enough (or maybe too much) e-mail and I'm reluctant to clog up my inbox with more stuff -- especially if it's information that's located elsewhere (such as on that big backup drive that we call "the Internet").

tipsextra_conceptBut on the other hand, I don't usually have time to go searching the Web for stuff that might someday be useful to me, or even to pay regular visits to the sources that I know will have good information (such as blogs and discussion forums). If someone collected some of the best tidbits from these sources and delivered them to me -- even in e-mail -- I think that would be useful. Do you agree?

We know from experience that SAS users love to see tips about how to do more with SAS. So we got to thinking: What if we curated an e-mail newsletter that was ALL SAS tips? Where all of the content was coming from the "hey, we bet you didn't know this" category?

We're making that happen, beginning this month. It's called SAS Tech Report: Tips Extra. It contains tips -- some from SAS staff and some from the larger SAS community -- to save you time and expand your mind. If you subscribe to the SAS Tech Report newsletter already, then do nothing -- you'll receive it automatically. If you don't yet subscribe, then visit the e-Newsletters section of and click the link to sign up. It's free, of course -- all you need is a SAS profile (which you probably already have if you participate in or interact with SAS Technical Support).

I hope that you like the content, and that you appreciate it showing up in your inbox. And if you have feedback or ideas for topics to feature, let me know here in the comments.

Post a Comment

Performance tips for viewing data in SAS Enterprise Guide

SAS users love to look at data. And the data grid in SAS Enterprise Guide is a convenient way to view the contents of a data set. While small data sets can be rendered lickity-split for quick viewing, sometimes people get justifiably anxious when opening very large data. Perhaps they've been burned with a bad experience, because opening a huge transaction table can hang up a system. When dealing with very large data, it's wise to be cautious.

In general, the SAS Enterprise Guide data grid can open and show data quickly, even if the data sets are very large. This is because the data grid does not read in all of the data records at once, but reads in only the records that are needed to fill the rows of the grid. The data grid uses a "virtual mode", which allows you to scroll quickly around your data set, no matter the size.

In addition to the scroll bar, which shows you approximately where you are in the data set, there are a few keyboard shortcuts that can help you to navigate:

  • Ctrl+End - takes you to the last record, last column in the data set.
  • Ctrl+Home - takes you to the first record, first column in the data set.
  • Ctrl+G - brings up a "Go to" window, in which you specify exactly which record number to bring to the top of the view.

Note: The concept of "record number" is a specific to SAS data sets, since traditional SAS files store records sequentially. When you view a database table (accessed through a SAS/ACCESS library), the idea of "record number" might not make as much sense, since the database rules determine the sequence. However, you can still use the keyboard shortcuts to navigate your view.

Even for all of its built-in smarts, the data grid can still perform slowly in certain situations. If you're experiencing slow performance, here are some tips to help.

Understand your network latency. SAS Enterprise Guide retrieves data records from your SAS session, which is typically on another machine in your network. If your network connection is slow or the remote machine is very remote (such as in another country), fetching those records will take more time.

Avoid opening data unnecessarily. When you add data to your project, whether using File->Open Data or by running a task that produces output data, SAS Enterprise Guide will automatically open the data for viewing. Simply opening the data can cause a noticable delay when there is network latency or a slow database connection. If you're already familiar with the data and don't need to see the records every time, you can change this default behavior. From Tools->Options, select Data General and uncheck the option for "Automatically open data when added to the project."

Avoid scrolling through very wide data. As I stated earlier, large data isn't generally a problem in SAS Enterprise Guide. However, when the data are very wide, the grid can be slow. Why? Because even though the data grid reads only enough data records to fill the grid, it reads only entire records -- even if some of the variables in the record aren't visible on the screen at the time.

I define "wide" data as hundreds or thousands of variables, or maybe fewer variables that each have very large lengths. Consider these two LENGTH statements, each of which allocate 2000 variables but yield dramatically different record lengths:

/* 2000 numeric vars, 8 bytes each = 16,000 bytes per record */
/* a data set with just these fields can render quickly in SAS EG */
length x1-x2000 8;
/* 2000 character vars, 1000 bytes each = 2,000,000 bytes per record! */
/* a data set with these fields can really slow things down */
length c1-c2000 $ 1000;

Use the Data Explorer with care. The Data Explorer (added in SAS Enterprise Guide 5.1) is a popular new feature (see Marje Fecht's enthusiastic review). The Data Explorer can provide at-a-glance "Quick Stats" of variable distribution and frequency. However, the behind-the-scenes analyses that support those stats can be expensive for very large data. SAS Enterprise Guide sets some automatic constraints in order to limit the impact, but you should set your expectations accordingly.

Understand the special treatment for database tables. When you access data in a library using a SAS/ACCESS engine (for example, connecting to Oracle or Teradata), SAS Enterprise Guide automatically limits the data grid view to 10,000 records. You can configure that number in the application options, but the reason for the constraint is to limit the impact on the database connection and to keep your DBA happy (well, as happy as DBAs tend to be, anyway). 10,000 records should be enough for you to "eyeball" the shape of the data. If you need to see rows that meet specific criteria, consider using the Query Builder.

To paraphrase King Burger's Bon Qui Qui (from the famous MAD TV sketch): You can view your data your way, but don't get crazy. I hope that with a little knowledge about what happens behind the scenes, you can click through your data with more confidence.

Post a Comment

New course: Developing Custom Tasks for SAS Enterprise Guide

This probably won't surprise any of my regular readers: "SAS custom tasks" is one of my favorite topics to talk about.

Since 2007, I've written blogs about how you can use custom tasks to extend SAS Enterprise Guide and the SAS Add-In for Microsoft Office. I've shared lots of examples, many that you can use simply "as-is" without any special technical knowledge. I presented a SAS Talks webinar on the topic. And I even wrote the book: Custom Tasks for SAS Enterprise Guide Using Microsoft .NET.

Now I'm ready to take this show on the road, and teach this topic in a classroom setting. I've built a new SAS course: Developing Custom Tasks for SAS Enterprise Guide.

I taught the course for the first time this past April. All new SAS courses go through a "test teach", in which internal SAS folks participate as students. The purpose of a test teach is to ensure that the course materials, software setup, and instructor are all up to the high standards for SAS Training offerings. In my test teach, I had students from Technical Support, R&D, Product Management, Education, and Professional Services. That's a pretty good mix, and I got some good feedback. At the end, we agreed that the course is ready for prime time.

Here are some high-level features that you can expect from the course:

  • It's a two-day course -- and we fill the time!
  • We cover the SAS APIs and toolkits that make custom tasks possible. We also cover best practices for design and build, which make it much easier to have successful custom task projects.
  • Students will get plenty of hands-on experience, some as instructor-led tutorials and some as independent lab exercises.
  • You will build a complete custom task, in class!
  • You don't need to be a SAS expert or Microsoft .NET expert coming in, but I recommend that you have base SAS programming experience and also experience with some object-oriented development tool, such as Microsoft Visual Studio (C# or Visual Basic) or Eclipse (with Java).
  • You should come having at least working knowledge of SAS Enterprise Guide.

If all of this sounds interesting to you, I hope to see you in a SAS training center in the near future! Check the SAS Training & Books web site for schedules and locations. (Note, this link is from the USA course catalog. Other countries might add the course later, based on interest. Hint, hint.)

Post a Comment

Add a stars-style rating column to your SAS output

Now, the Star-Belly Sneetches
Had bellies with stars.
The Plain-Belly Sneetches
Had none upon thars.
- from "The Sneetches", by Dr. Seuss

Recently a user on the SAS-L mailing list had this challenge: "I would like to display stars in a table (created by PROC REPORT) based on variable values. For example, if value=3, then display five stars with 3 in yellow, and the other two in grey."

In her original post, the user had sketched out an approach that used a custom SAS format with uppercase and lowercase Xs representing the desired "star" states. It turns out that this was very close to a working approach. All she needed to do was apply the same technique that I used to add Harvey Balls to a SAS report. Like the Fix-It-Up Chappie, I'm here to offer the solution.

In my Harvey Balls example, I used ODS ESCAPECHAR and Unicode character codes to add extended characters to my SAS format labels. There is a Unicode character for a star (HEX 2605), so the same approach can work. In addition, the ESCAPECHAR sequence can set off style instructions, such as a color definition. This allows you to control the character color "mid-stream". For example, this sequence specifies a red star followed by a gray star:

 ~{style [color=red] ~{unicode '2605'x}} ~{style [color=ygr] ~{unicode '2605'x}}

As it happens, I keep some movie rating data that I downloaded from my Netflix account history (a very rich source of trivial SAS examples). When I apply a custom "star" format to my data, I can produce a report like this:
Here's my SAS format and the PROC PRINT code that references it. The format and report look perfect in HTML, PDF and RTF output:

/* ODS EXCAPECHAR needed to set style/unicode cues */
ods escapechar='~';
/* Captured these in macro variables for readability and */
/* easy maintenance                                      */
%let graystar = ~{style [color=ygr] ~{unicode '2605'x}};
%let redstar =  ~{style [color=red] ~{unicode '2605'x}};
/* using a 4-star system where 1 means "zero stars" */
/* and 5 means the full "4 stars"                   */
proc format lib=work;
value stars
 1 = "&graystar.&graystar.&graystar.&graystar."
 2 = "&redstar.&graystar.&graystar.&graystar." 
 3 = "&redstar.&redstar.&graystar.&graystar." 
 4 = "&redstar.&redstar.&redstar.&graystar." 
 5 = "&redstar.&redstar.&redstar.&redstar." 
title "Movie titles with STARS on THARS";
proc print data=work.movies noobs;
  format rating stars.;

If you want to try it yourself, you can download my program with test data:

>> Complete SAS program with test data

This program should work in SAS Display Manager, SAS Enterprise Guide (select HTML output), and even the SAS University Edition (SAS Studio).

Post a Comment

Cage match: SAS Studio versus SAS Enterprise Guide

I wish I had a nickle for every time I heard this question at SAS Global Forum:

"So, does this SAS Studio thing replace SAS Enterprise Guide?"

SAS Studio is a pretty big deal. It's groundbreaking in several ways:

  • It's a web-based programming interface to SAS. It runs in your browser, which means that end users don't have to install anything (when connecting to a remote SAS session).
  • It's an HTML5-based application, so there are no browser plugins needed. It runs on Windows, Macs, and even the iPad.
  • It's the basis for new offerings from SAS, most notably the SAS University Edition. This offering is free to just about any learner for non-commercial use. The SAS University Edition includes SAS, running in a virtual machine, packaged with SAS Studio as the user interface. Since its launch earlier this week, people have been downloading it like crazy.

You're going to be hearing a lot about SAS Studio. It was even the theme for this month's SAS Tech Report.
If you haven't seen SAS Studio, take a few minutes and watch my SAS Tech Talk interview with Shannon Smith, the SAS R&D testing manager for the product:


So what does this mean for those of us who have invested our skills and processes in SAS Enterprise Guide? If you read this blog regularly, you know that includes me! Does this "new app on the block" replace our beloved SAS Enterprise Guide? The answer is No -- and Yes.

No, SAS Studio isn't a direct SAS Enterprise Guide replacement. SAS Enterprise Guide continues to get new features, mostly targeting productivity enhancements and integration with other SAS offerings, such as SAS Visual Analytics. Many thousands of users around the world use SAS Enterprise Guide to manage process flows, reporting and analytics, database access, and custom processes. SAS Studio doesn't have all of that infrastructure (at least, not yet), and cannot step in to replace all of that.

But also, Yes: SAS Studio can replace some uses of SAS Enterprise Guide. If you use SAS Enterprise Guide simply as way to manage SAS programs in your SAS environment, then you can certainly use SAS Studio instead (or as well) to develop and maintain those programs. SAS Studio also includes some tasks for non-programmers, similar to those found in SAS Enterprise Guide -- but for now the library isn't as rich as what you'll find in SAS Enterprise Guide. And with the SAS University Edition, SAS Studio will represent the first SAS experience for the next generation of SAS programmers.

Sometimes SAS users ask me (usually in a hushed tone): Why does SAS create these different applications that seem to compete with each other? Is there some sort of contest in SAS R&D to see which teams can outdo the others? My answer: while these apps might have a certain amount of overlap, they really do serve different purposes and different audiences. Our goal is to enable SAS users -- regardless of discipline, industry, or expertise -- with the tools that are most fit for their particular purpose. One size does not fit all (though some diehard PC SAS fans might disagree with me).

Plus, here's another secret: the same developers have built all of these applications. The SAS Studio development team includes people who worked on SAS Display Manager (you know, "PC SAS") and SAS Enterprise Guide. This is a direct benefit of SAS being such a great workplace: nobody leaves. That means that the lessons learned from customers and developers are carried over and applied in each successive "app generation". If developers are competing, then they are mostly competing with the proven work they've done in the past. But since the teams always have new technology and techniques at their disposal, it's the end users who win.

Post a Comment

The ingredients of a Data Scientist

It was just a couple of years ago that folks were skeptical about the term "data scientist". It seemed like a simple re-branding of an established job role that carried titles such as "business analyst", "data manager", or "reporting specialist".

But today, it seems that the definition of the "Data Scientist" job role has gelled into something new. At SAS Global Forum 2014, I heard multiple experts describe data science qualifications in a similar way, including these main skills:

  • Ability to manage data. Know how to access it, whether it's in Excel, relational databases, or Hadoop -- or on the Web. Data acquisition and preparation still form the critical foundation for any data analysis.
  • Knowledge of applied statistics. Perhaps not PhD-level stuff, but more than the basics of counts, sums, and averages. You need to know something about predictive analytics, forecasting, and the process of building and maintaining analytical models.
  • Computer science, or at least some programming skills. Point-and-click tools can help keep you productive, but it's often necessary to drop into code to achieve the flexibility you need to acquire some data or apply an analysis that's not provided "out of the box".
  • And finally -- and this makes a Data Scientist the most relevant -- the ability to understand and communicate the needs of the business. You might be a data wiz and have metrics out the wazoo, but an effective data scientist must know which fields and metrics matter most to the organization he or she serves. And you must be able to ask the right questions of the stakeholders, and then communicate results that will lead to informed action.

I don't claim to be a data scientist -- I'm not strong enough in the statistical pillar -- but I do have my moments. For example, I consider my recent analysis of blog spam to be data-science-like. Even so, I'm not brave enough to change my business cards just yet.

At SAS Global Forum I talked to Wayne Thompson, Chief Data Scientist at SAS. (Yes, even SAS is capitalizing on the buzz by having a data science technologies team.) Here he is introducing SAS In-Memory Statistics for Hadoop, a programming interface that's meant to empower data scientists:

Wayne and I also talked a couple of other times: once about SAS Visual Statistics ("it's the shizzle", says the bald white guy -- not me), and once about data science in general.

Data science isn't all just "Wayne's world" -- there were plenty of other data science practitioners at the conference. For example, check out Lisa Arney's interview with Chuck Kincaid of Experis, talking about how to be a data scientist using SAS. (See his full paper here.) And SAS' Mary Osborne, who presented on Star Wars and the Art of Data Science. (Her paper reveals the unspoken fifth pillar of a data scientist: it's good to be part nerd.)

What do you think about the "new" field of data science? Have you changed your business card to include the "data scientist" title?

Post a Comment

Adding Harvey Balls to your SAS reports

I'm currently working on a large project for a SAS customer. The project comprises many activities and phases, so there is a need to track progress on many different levels. During a recent meeting the project manager announced, "I'm putting together a status deck, and I'll include some Harvey Balls for each item."

"Harvey whats?" I said, nearly spitting out my coffee.

I've since learned that Harvey Balls are a project-management thing. They are used as way to communicate qualitative progress towards a goal: not just whether an item is complete, but also how far along it is. (Please, don't confuse these with Harvey wallbangers, which are used to measure progress towards something else.) Harvey Balls remind me of the little circles that I see in Consumer Reports product reviews.

A web search will yield lots of examples of how to add Harvey Balls to your PowerPoint slides and Excel spreadsheets -- favorite domains of project managers. However, there isn't much (any?) about how to use these in SAS, so with this blog post I hope to corner the market.

First, a visual -- here's what Harvey Balls look like in a SAS report:

It turns out that the Harvey Ball glyphs are built into some of the fonts that you probably have installed, and can be accessed by referencing their Unicode character values. For ODS-based reports, we can include any Unicode character that we need by using:

  • the ODS escape character, combined WITH...
  • the {unicode} keyword, AND..
  • the hexadecimal code of the character we want.

For example:

ods escapechar='~';
title "This is a full-circle Harvey Ball: ~{unicode '25CF'x}";

yields this:

For a more data-driven approach, I decided to encode the Harvey Balls in a numeric SAS format. In my mapping, I set values between 0 and 4, inclusive. 0 means "empty" or no progress, whereas 4 means "full" or complete. 1 through 3 represent a quarter, halfway, and three-quarters, respectively.

ods escapechar='~';
proc format lib=work;
value hb  
  0 = "~{unicode '25CB'x}" /* empty circle */
  1 = "~{unicode '25D4'x}" /* quarter */
  2 = "~{unicode '25D1'x}" /* half */
  3 = "~{unicode '25D5'x}" /* three-quarter */
  4 = "~{unicode '25CF'x}" /* full */

Here's a partial listing of the PROC REPORT code that uses the format. Note that I added some other appearance treatments to the report column with the Harvey Ball. Because the font glyph tends to be small, I bumped up the font size to 18 points. I also specified Lucida Sans Unicode as the font face because I know that font contains the right glyphs. Finally, I tweaked the alignments to account for the larger padding that accompanies the larger font size, ensuring the data looked vertically aligned properly in each row.

proc report data=progress;
 columns  stage dev test prod;
 define stage / 'Activity' display style=[verticalalign=center];
 define dev  / '% Dev' format=hb.
   font_face='Lucida Sans Unicode' 
/* ... */

>> Download the complete example program from here. (Should work with SAS 9.2 or later)

Bonus: If you have SAS 9.4, you can modify this program to place the report directly into PowerPoint! This makes it perfect for consumption by project managers everywhere.

ods powerpoint file="c:\temp\hb.pptx" style=PowerPointLight;
/* proc report section here...*/
ods powerpoint close;

Here's a screenshot of the result (click to see it full size):


See also

The Power of Unicode (using these characters in SG plots)
Unicode Tick Values using GTL
The Great Escape(char) - great paper by SAS user Louise S. Hadden

Post a Comment

Blog spam: ain't nobody got time for that

Here at SAS, we've come a long way with how we deal with blog spam on

Last year at this time, I was sifting through dozens of spam messages per day in order to salvage the one or two genuine comments that originate from real readers. I was just a human trying to keep up with machine-generated spam, a time-consuming -- and somewhat frustrating -- activity.

I created SAS-based reports that showed the impact not just on me, but on the hundreds of other SAS blog contributors. Thankfully in May, our internal IT support configured an industry-standard spam-filtering mechanism called Akismet. The spam flow ceased immediately, as if somebody turned a spigot.

Recently, the spigot has been turned on slightly, allowing a few spam messages to leak through. The spammers are like an ever-evolving virus, constantly adapting their techniques to punch through our defenses. I wondered: with the leaks I'm seeing, how effective is Akismet for us today?

It turns out that Akismet is very effective. Despite the few messages that I see leak through daily, Akismet is catching over 95% of the spam messages that target our blogs. Over the last 16 days I saw 40 spam notifications hit my inbox. Without Akismet, I would have seen 741 messages in the same period. Yikes.

akismetdbI can see some of this within my WordPress blog administration screen, since the Akismet plugin embeds a sort of dashboard there. This is useful for me, but we have over 30 blogs hosted at As far as I know, we don't have a view into how Akismet is performing for our entire set of blog properties.

Enter SAS. By using SAS to connect to the WordPress database (something I already do for other reports), I can scrape and aggregate the Akismet metrics for a more global report on spam activity. Here's an example of a chart that I created:


In this chart, the height of the blue bar indicates the total number of incoming spam on each day, across all blogs. The smaller green bar indicates the number of "author-identified spam" messages -- those that the filter did not catch and that the blog moderator had to mark as spam. The number at the top of each bar indicates a "percent missed" for the day. And finally, the text at the bottom of the chart provides a summary: total spam caught, total missed, and a percentage. Since we receive so much spam, the IT folks configured Akismet to purge our spam data every 3 weeks or so. That's why the chart shows only a 16-day study period. (See an example of the full report here.)

Interested in the SGPLOT code behind this chart? It looks something like this (data prep steps omitted, of course):

proc sgplot data=reckoning;
  format comment_date dtdate5. fail_rate percentn6.2;
  label spam_caught='Spam caught' spam_allowed='NOT caught';
  vbar comment_date / response=spam_caught dataskin=pressed
  datalabel=fail_rate datalabelfitpolicy=none 
    datalabelattrs=(color=black size=10pt);
  vbar comment_date / 
     response=spam_allowed barwidth=.6 dataskin=pressed 
  yaxis label="Akismet ruling" grid;
  xaxis valueattrs=(size=9) 
    label="Spam comments (&total_caught. caught, &total_allowed. allowed - &overallfail. missed overall)";

Assuming that it takes a blog moderator just a few seconds to evaluate and dispose of each spam message, Akismet has saved us a collective several hours over the weeks we see here. However, as we can see from the metrics accumulated over time, this really adds up:

I don't think that Akismet costs us very much, and -- in my view -- the time that we save is definitely worth the expense. Spammers will always be with us and are just part of the cost of publishing content. But dealing with it manually? Ain't nobody got time for that.

Post a Comment

Take control of ODS results in SAS Enterprise Guide

When you run a program or task in SAS Enterprise Guide, the application wraps your job in an "ODS sandwich", the colloquial term we use for the ODS statements necessary to create output that can be viewed in your project.

That's convenient for exploring and refining your program, but at some point you might want to use your own ODS statements and options to control the format and appearance of the output. You might find that the default ODS sandwich that SAS Enterprise Guide generates can get in your way.

For example, suppose that you want to create a PDF output with landscape orientation and Legal paper size. The default SAS Enterprise Guide options might be in conflict with some of the options you need. The best approach? Squelch the "automatic" options, and code up your own exactly how you need them. Here's how.

First, change the properties of your SAS program.. Right-click on the program node in your flow and select Properties, or click the Properties icon at the top of the editor window:


In the Properties window, select the Results tab. Then select the Customize results formats [...] option, and uncheck all of the built-in formats.

Next, add the ODS statements and options necessary to produce the results that you want. For example, if you want a PDF file that has a particular format, use something like this:

options orientation=landscape papersize=legal;
ods noproctitle;
/* using ID= to control each ODS dest */
ods pdf (id=custom) 
  /* this file path is on the SAS workspace */
  columns=2 style=journal;
  title "Types by Cylinders and MSRP stats";
proc freq;
  table Type * Cylinders;
proc means;
  class Origin;
  var msrp;
/* print-friendly image options */
ods pdf (id=custom) dpi=300 startpage=no;
ods graphics / 
  noborder scale=on
  height=2in width=2.5in;
title "Distribution";
proc sgplot;
	histogram msrp;
	density msrp;
ods pdf (id=custom) close;

Sample result:
Link to PDF
Some notes about this program:

  • The FILE= option on the ODS PDF statement refers to the file that you want to create in the file system of your SAS workspace, not your local machine. SAS Enterprise Guide will offer to download this file for you to view, but if you want complete control over where it lands on your local PC, use the Copy Files task to download it.
  • If you run this program in SAS Enterprise Guide without turning off the other Results formats, the final PDF output won't have all of the attributes you expect. For example, the graph might look slightly different. So if this PDF is your ultimate objective, be sure to suppress the automatic results from SAS Enterprise Guide.
  • Use this same technique to create custom HTML output, or ODS POWERPOINT (new in 9.4), ODS EPUB (new in 9.4) or even ODS HTML5 (hey! new in 9.4).

For a minimalist, fast-running SAS program, you can use this technique to suppress the fancy (bulkier) ODS results and rely on the old-school LISTING format. In the Results properties for your program, uncheck all output destinations except for Text. If your program generates only text-based output that you want to view quickly, this will turn SAS Enterprise Guide into a speedy-quick results-generating machine...just like you might be accustomed to from your old PC SAS days.

See also

Destination Known: Programmatically Controlling Your Output in SAS Enterprise Guide, by Aaron Hill
[VIDEO] New Destinations in ODS: PowerPoint, HTML5, EPUB, EXCEL
Tip Sheet for ODS PDF

Post a Comment