How to split one data set into many

splitdataBack in the day when the prison system forced inmates to perform "hard labor", folks would say (of someone in prison): "He's busy making little ones out of big ones." This evokes the cliché image of inmates who are chained together, forced to swing a chisel to break large rocks into smaller rocks. (Yes, it seems like a pointless chore. Here's a Johnny Cash/Tony Orlando collaboration that sets it to music.)

SAS programmers are often asked to break large data sets into smaller ones. Conventional wisdom says that this is also a pointless chore, since you can usually achieve what you want (that is, process a certain subset of data) by applying a WHERE= option or FIRSTOBS=/OBS= combination. Splitting a data set creates more files, which occupy more disk space and forces more I/O operations. I/O and disk access is often the most expensive part of your SAS processing, performance-wise.

But if the boss asks for broken-up data sets, you might as well spend the least possible effort on the task. Let's suppose that you need to break up a single data set into many based on the value of one of the data columns. For example, if you need to break SASHELP.CARS into different tables based on the value of Origin, the SAS program would look like:

DATA out_Asia;
DATA out_Europe;

I'm going to admit right now that this isn't the most efficient or elegant method, but it's something that most beginning SAS programmers could easily come up with.

Writing the above program is easy, especially since there are only 3 different values for Origin and I've memorized their values. But if there are more discrete values for the "split-by" column, the task could involve much more typing and has a high possibility for error. This is when I usually use PROC SQL to generate the code for me.

If you've read my article about implementing BY processing for an entire SAS program, you know that you can use PROC SQL and SELECT INTO to place data values from a data set into a macro variable. For example, consider this simple program:

proc sql;
 select distinct ORIGIN into :valList separated by ',' from SASHELP.CARS;

It creates a macro variable VALLIST that contains the comma-separated list: "Asia,Europe,USA".

But we can use SAS functions to embellish that output, and create additional code statements that weave the data values into SAS program logic. For example, we can use the CAT function to combine the values that we query from the data set with SAS keywords. The results are complete program statements, which can then be referenced/executed in a SAS macro program. I'll share my final program, and then I'll break it down a little bit for you. Here it is:

/* define which libname.member table, and by which column */
%let COLUMN=origin;
proc sql noprint;
/* build a mini program for each value */
/* create a table with valid chars from data value */
select distinct 
   cat("DATA out_",compress(&COLUMN.,,'kad'),
   "; set &TABLE.(where=(&COLUMN.='", &COLUMN.,
   "')); run;") into :allsteps separated by ';' 
  from &TABLE.;
/* macro that includes the program we just generated */
%macro runSteps;
/* the macro when ready */

Here are the highlights from the PROC SQL portion of the program:

  • SELECT DISTINCT ensures that the results include just one record for each unique value of the variable.
  • The CAT function concatenates a set of string values together. Note that CATX and CATS and CATT -- other variations of this function -- will trim out white space from the various string elements. In this case I want to keep any blank characters that occur in the data values because we're using those values in an equality check.
  • The program calculates a name for each output data set by using each data value as a suffix ("OUT_dataValue"). SAS data set names can contain only numbers and letters, so I use the COMPRESS function to purge any invalid characters from the data set name. The 'kad' options on COMPRESS tell it to keep only alpha and digit characters.
  • The resulting program statements all end up in the &ALLSTEPS macro variable. I could just reference the &ALLSTEPS variable in the body of the SAS program, and SAS would run it as-is. Instead I chose to wrap it in the macro %runSteps. This makes it a little bit easier to control the scope and placement of the executable SAS program statements.

"By each value of a variable" is just one criterion that you might use for splitting a data set. I've seen cases where people want to split the data based on other rules, such as:

  • Quantity of observations (split a 3-million-record table into 3 1-million-record tables)
  • Rank or percentiles (based on some measure, put the top 20% in its own data set)
  • Time span (break up a data set by year or month, assuming the data records contain a date or datetime variable)

With a small modification, my example program can be adapted to serve any of these purposes. What about you? Are you ever asked to split up SAS data sets, and if so, based on what criteria? Leave a comment and tell us about it.

Post a Comment

SAS employees are now easier to spot on Communities

Since the launch of Communities on SAS, hundreds of SAS employees have been among you. Some SAS employees made themselves known by selecting a telling user name (such as Cynthia@SAS), but others remained camouflaged or incognito, keeping their secret identities like the SAS superheroes they are.

That's about to change. This week, we are revealing all SAS staffers on the Communities by changing their status indicators to "SAS Employee", featuring the familiar SAS logo. We're making this change to help make Communities on SAS more valuable and relevant to you. We know that you enjoy interacting with SAS employees here; now you'll have a clearer view into when that's happening.

You'll see this take effect in several places. For example, for the communities that have a "Top Participants" roll, you might see some SAS folks appear in the list:

When you hover your mouse cursor over a user name, or drill down to see more details about a community member, you will also see the "SAS Employee" designation.

With the introduction of the "SAS Employee" status, you will no longer see the familiar "rank" status for these users. So you won't be able to tell -- at a glance -- whether a SAS Employee has achieved Expert, Master, or merely Novice levels of contribution. We hope that you'll appreciate all SAS employees as experts in their respective areas, even if the ranking isn't spelled out for you.

We hope that you enjoy the change. If you have feedback or ideas, please let us know!

Post a Comment

Using SAS Enterprise Guide with your local SAS installation

serverlist_withlocalIf you have SAS Enterprise Guide and SAS for Windows installed on a machine together, they should Just Work. There is no special setup required. But...what if they don't?

I've posted an article in the SAS Enterprise Guide community about this topic. Read the article to learn:

  • How to select "No profile" mode in SAS Enterprise Guide.
  • How to add your Local SAS into the mix when you're connected to a SAS Metadata environment
  • How to "fix" your local system when SAS Enterprise Guide can't find your local SAS installation.

See the full article >> Using SAS Enterprise Guide with your local SAS installation

If you find the article to be helpful, please give it a rating. (You will need to sign in with your SAS profile to add a rating.) Positive ratings will make it easier for other users to find the information. And if you think the article needs something else to make it more useful, leave a comment on the article or here on the blog.

Side note about Communities on SAS

I've always been a big fan of the Communities on SAS, where thousands of SAS practitioners interact to learn from each other. A good number of SAS employees also participate in the discussions, which means that many of the answers about SAS technology are coming directly from the developers who created it. But it's your participation that makes the communities rich and engaging.

And now I have a more professional interest in the communities, as I've just moved into the role of managing our SAS Online Communities program. My team of community managers would love to hear from you about what you like and what you think could be improved. We have big plans for the communities program, and your input is essential to help us build the space where you want to spend your time. Post back in the comments here, or send us your feedback using this form (select Discussion Forums or Communities as the category).

Post a Comment

Why your DDE programs don't work anymore

Hello, 1992 called. They want their DDE Excel automation back.

DDE broken?Perhaps the title of this article is too pessimistic. Of course your SAS programs that use DDE (dynamic data exchange) can still work perfectly, as long as you situate your SAS software and its DDE "partner" (usually Microsoft Excel) to run on the same Windows PC. DDE is still documented and supported in SAS 9.4.

But for the growing number of users who modernize to a centralized SAS environment, the legacy of DDE is a big challenge to bring forward. Your new environment might include the benefits of SAS Grid Computing, SAS Visual Analytics, stored processes, and more manageable security. You might run your SAS programs using SAS Enterprise Guide or even a web browser. But with all of that shiny new tech and its distributed architecture, the simple local arrangement that allows DDE to function...well, it falls apart.

Let's look at how DDE works. This data exchange relies on two consenting Windows processes, both running on a single machine, to communicate with each other using special Windows messages. In SAS programs, this usually takes the form of SAS spawning Microsoft Excel, sending a command to reference a particular cell or range of cells in a sheet, and poking in some values that were computed in SAS. If your SAS session is now running on a remote machine (often a non-Windows machine), then SAS cannot use DDE to talk to your local Microsoft Excel application. As the man says, "what we've got failure to communicate."

For those customers who have a lot invested in DDE (some have hundreds of programs!) and no time/budget to adjust processes away from it, I usually recommend a simple stop-gap approach: maintain a designated machine with SAS for Windows to do your DDE grunt work, even as you move other processes to an enterprise SAS environment.

But going forward, I encourage customers to look at the alternatives supported by new features in SAS that are more in line with today's topology (SAS on a remote server, SAS Enterprise Guide or other local client on the PC). These features can replace many (but not all) of the legacy DDE uses that are out there.

DDE is still supported in Microsoft Excel. We cannot say for how long, as Microsoft has put more emphasis on VBA, .NET, or PowerShell for Excel automation instead. But since DDE works only between two Windows processes (SAS and Excel in this case) on the same machine, it's an outmoded approach that's incompatible with many IT setups.

Some DDE alternatives

The SAS Add-In for Microsoft Office offers the most flexible method for complete control over the format and structure of your spreadsheet. It turns the problem on its head: instead of relying on a batch SAS program to push content into Excel, you simply use Excel to pull your SAS content into the spreadsheet, exactly where and how you want it. You can use SAS stored processes to encapsulate whatever SAS operation you need.

Within the SAS Add-In, you can also use specific cells and ranges as input into stored processes; it's just as flexible to inject your Excel content into SAS.

You can use Office scripting to automate the process (like a batch job), so the process can happen unattended. The consumers of your Excel documents do not need the SAS Add-In for Microsoft Office in order to view the results.

I know that not everyone is lucky enough to have the SAS Add-In. For batch SAS users, ODS tagsets.ExcelXP -- or its SAS 9.4 descendant ODS EXCEL -- can be used to place formatted report content into an Excel spreadsheet. Here's an example use for ODS EXCEL, which works as a "one-way" push from SAS into Excel.

Also, PROC EXPORT now supports adding sheets to existing files, or replacing entire sheets in place. That's flexibility that didn't exist before, when some users turned to DDE to fill the gap.

Aside from these SAS-centric approaches, creative programmer types can use script (VBS, PowerShell, and other) to plug their SAS data results into a spreadsheet as a post-process (which many customers spawn within their SAS programs).

Thinking of DDE as technical debt

Weaning yourself off of DDE is easier said than done, I'll admit. Twenty years ago DDE was a boon for SAS developers who needed to deliver Excel content to picky constituents. I played my part: I wrote the SAS Companion for Microsoft Windows (Release 6.11!) and crafted some of the examples that still exist in the documentation.

However, I now consider DDE programs to be a form of "technical debt" that organizations will have to pay off sooner or later.

If your "DDE bill" hasn't come due yet, you're fortunate. But if you're planning to write another SAS program that relies on DDE, consider the future generations. Today's kids are writing SAS programs in iPads and web browsers, and DDE is about as hip as a rotary-dial phone. (Yes, it still works, but it does make your fingers tired.)

Post a Comment

New SAS programming features in SAS Enterprise Guide 7.1

SAS Enterprise Guide 7.1 began shipping last week. Of the many new features, some are "biggies" while others are more subtle. My favorite new features are those for SAS programmers, including several items that I've heard customers ask for specifically. I'll describe them briefly here; the SAS Enterprise Guide online help contains more details.

Track program history

This is one of the biggies. If you have SAS programs in your SAS Enterprise Guide project, you can now track your changes in those programs using standard source control management methods.

You can "commit", view history, revert changes, compare versions, and even see an annotated "blame" view that shows exactly when you introduced a change that broke your program.

The program history feature relies on a "hyperlocal" Git repository within your EGP file, so you can't use this to track changes to SAS programs that you store outside of the project. But SAS Enterprise Guide 7.1 also supports integration with a file-system-based Git repository if you set one up using other tools. The SAS integrated menus/tools will still help you to see your program's heritage.

Why Git? Functionally, it fits the purpose. And the SAS team was able to embed the necessary pieces within the application, so you don't need to install additional tools before getting started. And besides, all of the cool kids use Git these days. If you need to work with Subversion or another tool, you can still use this file-system technique.

Smart highlighting in the program editor

Double-click on a word in the editor to highlight it, and instantly see all other occurrences of that word highlighted in your program view. That's what puts the "smart" in "smart highlighting".

It's amazingly useful for finding all occurrences of a variable name, data set name, or an embarrassing misspelling.


Project log summary window

The Project Log shows you a complete aggregated view of your SAS logs within your project; it's been part of SAS Enterprise Guide for several years. The log content is comprehensive, but often difficult to navigate because it holds so much. Now the popular Log Summary view (introduced in release 6.1) has made it to the Project Log, simplifying your journey through the log content.


Project-level Search

The search for a "search" feature led me to create the EGP Search tool, which has been very popular among SAS Enterprise Guide "power users". Now there is a built-in search feature that allows you to search the current project for text in any project element, including tasks, programs, and results.


(The built-in search feature doesn't search multiple project files, so my EGP Search tool isn't obsolete just yet.)

SAS Macro Variable viewer and SAS System Options viewer

Many SAS programmers have downloaded these two custom tasks from this blog. The macro variable viewer shows all of the current SAS macro variables and their values, plus allows a quick method to evaluate macro expressions. The system options viewer shows all of the SAS options, with their values and meanings. Thanks to the popularity of the custom tasks, the R&D team agreed to include them in the main application. These tasks are now "first-class citizens" on the Tools menu.


But wait, there's more

I look forward to discussing more new features, including: integration with SAS Studio tasks, with SAS Visual Analytics and the LASR server, some new UI niceties for finding tasks and organizing Favorites, and much more. It's a big release with plenty of treasures to find -- and even I'm still discovering them!

Post a Comment

Don't panic: maybe your XLSX file is already opened

As you can tell from my recent posts (see here and here), I've been working with SAS and Microsoft Excel files quite a bit. I'm really enjoying the ability to import an XLSX file in my 64-bit SAS for Windows without any additional setup.

After one long afternoon of back-and-forth between Excel and SAS, I ran into this alarming error message:

ERROR: Error opening XLSX file -> C:\Projects\MyData.xlsx .  It is either not 
an Excel spreadsheet or it is damaged.   Error code=80001019
Requested Input File Is Invalid
ERROR: Import unsuccessful.  See SAS Log for details.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE IMPORT used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

It's a scary message, and I panicked -- but just briefly. I soon remembered that Microsoft Excel likes to place an exclusive file lock on spreadsheet, so if you have it open in Excel, nothing else will be able to read it. My file wasn't "damaged" -- it was simply in use.

I could wish for a better error message like: "Excuse me sir, but it appears that file is already opened by another application. Would you mind closing it so that we can read the data? I mean, whenever it's convenient for you."

Once I closed Microsoft Excel and reran my SAS program, all was good. Whew!

Post a Comment

Using ODS EXCEL and PROC EXPORT to bundle Excel-based reports

I recently wrote about my foray into the experimental world of ODS EXCEL. Using this new destination in SAS 9.4, I was able to create multisheet workbooks -- containing reports and graphs -- in the XLSX format. I outlined some of the benefits -- such as being part of Base SAS and its ability to create native XLSX files. But I also pointed out some of the shortcomings that I experienced, such as slow performance with large amounts of data.

I'm working on a consulting project in which I needed to provide my client with an Excel-based report. This report requires an easy-to-read summary sheet, such as might be created with PROC MEANS and PROC TABULATE. That's a perfect job for ODS EXCEL. But I also needed to include subsequent sheets that contained different versions of detailed data -- tables with lots of columns and many thousands of rows. In my experience, this can bog down ODS EXCEL; I find that PROC EXPORT with DBMS=XLSX performs much better. So...I decided to see if I could combine the two approaches to create a single file.

The process worked perfectly for my purposes. It relies on the following behaviors/assumptions:

  • ODS EXCEL creates a new XLSX file. That's okay, because each time I run my process I want to replace the XLSX that I had before. If I wanted to retain previous versions, I could tack a date suffix onto the target file name.
  • PROC EXPORT with DBMS=XLSX can add/update a sheet within an existing XLSX file. That's a relatively recent feature, added in SAS 9.4 (and perhaps worked in SAS 9.3M2). This means that I can create the file with ODS EXCEL, then update the same file using PROC EXPORT, all within a single SAS program. (Remember, PROC EXPORT with DBMS=XLSX requires SAS/ACCESS to PC Files.)

I would like to show an example of the output, but I'm sure that my customer wouldn't approve of me featuring their data details on my blog. So instead I'll risk alienating a different group of acquaintances: my Facebook friends.

Years ago I built an app that turns your Facebook friend data into a SAS program. Even though eons have passed (in social media time), the app still works. (You can try it yourself: it runs as a custom task in SAS Enterprise Guide or as a standalone program on your Windows PC.) I ran it just now to gather my latest Facebook friend data and create SAS data sets with my friend details. Then I used ODS EXCEL to create a summary sheet, and PROC EXPORT to create several detailed sheets. Here's an example of the summary:

And then one of the detailed sheets, produced by PROC EXPORT of one of the detailed data sets my Facebook program created:

Here's the SAS program that produces this output. First, I run the program that is generated by my Facebook app. Then I follow up with this program that generates the Microsoft Excel spreadsheet file.

/* Create a new FB summary and report workbook for this snapshot 
   of Facebook data                                             */
filename fbout "c:\temp\FBReport_&SYSDATE..xlsx";
/* A little ODS style trick to make headings in my sheet */
ods escapechar='~';
%let bold_style=~S={font_size=12pt font_weight=bold}~;
/* CREATES a new XLSX file */
ods excel (id=fb) file=fbout
  /* choose a style you like */
  /* SHEET_INTERVAL of NONE means that each PROC won't generate a 
     new sheet automatically                                     */
  options (sheet_interval="none" sheet_name="Summary")
ods noproctitle;
ods text="&SYSDATE. Friend Report for &myFacebookName";
proc sql;
     select count(distinct(UserId)) as 
         Number_Of_Friends into: NumberOfFriends
	 from friends;
ods text="&bold_style.Count of friends by gender";
proc freq data=frienddetails
	tables gender / 
ods text="&bold_style.Calculated Ages based on Graduation years";
proc means data=ages
	min max mean median p99;
	var age;
	class how;
ods graphics on / width=800 height=300;
ods text="&bold_style.Count of friends by Relationship Status";
proc freq data=frienddetails
	tables relationshipstatus / 
	scores=table plots(only)=freqplot;
ods excel (id=fb) close;
/* ADDS new SHEETS to the existing XLSX file */
proc export data=frienddetails
  outfile=fbout replace;
  sheet="Friend Details";
proc export data=schoolfriends
  outfile=fbout replace;
proc export data=statusprep(keep=name date message)
  outfile=fbout replace;
  sheet="Latest Status";

I could achieve a similar result using other methods, of course. But I like to take advantage of my consulting opportunities to explore new features in SAS software. I find that if I can learn a new feature "on the job", I can produce a good result for my customer while also adding to my bag of SAS tricks.

Related articles

Experimenting with ODS EXCEL to create spreadsheets from SAS
How do I export from SAS to Excel files: Let me count the ways
Running PROCs on Your Facebook Friends (2011 version)

Post a Comment

Experimenting with ODS EXCEL to create spreadsheets from SAS

The ODS ExcelXP tagset has served us well over the years. It provides a reliable method to get formatted SAS output into Microsoft Excel workbooks, where the business world seems to like to live. And it's available in Base SAS, which means that you don't need SAS/ACCESS to PC Files and any extra setup to begin using it.

In SAS 9.4 Maintenance 1, ODS EXCEL was introduced as an experimental feature. Even though it still has the "experimental" label in the recently released SAS 9.4M2, I've found it to be a useful addition to the many ways I can create Excel content from SAS. ODS EXCEL offers a couple of big advantages over ExcelXP:

ODS EXCEL produces a native XLSX file. Users of the ExcelXP tagset know that Excel complains about the file format as you open it. And the XML Spreadsheet format that it uses is uncompressed, resulting in potentially very large files.

ODS EXCEL supports SAS graphics in the output. ExcelXP users have come up with creative methods to insert graphs "after the fact", but it's not as convenient as a "once and done" SAS program. With ODS EXCEL, graphics from SAS procedures are automatically included in output.

Syntax-wise, ODS EXCEL is similar to ODS TAGSETS.ExcelXP. Chevell Parker shares many of those details in his SAS Global Forum 2014 paper; in absence of official doc for this experimental feature, Chevell's paper is essential.

Let's dive into an example. The following program looks similar to how you might use the ExcelXP tagset, but can you see the key differences?

ods excel file="c:\projects\output\example.xlsx" 
 /* will apply an appearance style */
  /* for multiple procs/sheet */
  /* name the sheet tab */
  sheet_name="CARS summary"
/* add some formatted text */
ods escapechar='~';
ods text="~S={font_size=14pt font_weight=bold}~Cars Summary and Histogram";
/* tabular output */
proc means;
var msrp invoice;
/* and a graph */
ods graphics / height=400 width=800 noborder;
proc sgplot;
histogram msrp;
ods excel close;

Note how I've targeted an XLSX file directly, instead of going through an XML intermediary file to placate Excel with the file format. And I included a graph with no problem. Like other ODS output destinations, I can apply styles and special formatting as needed. Here's a screen shot of the resulting spreadsheet:


I have a few additional observations from playing with this feature (did I say it was experimental?):

  • ODS EXCEL doesn't perform well with large detailed output. That is, if I use ODS EXCEL and PROC PRINT a data set with lots of columns and many thousands of rows, it's going to be slow -- and might hit a wall with memory usage. For that use case, PROC EXPORT DBMS=XLSX works better (though that requires SAS/ACCESS to PC FILES).
  • ODS EXCEL overwrites any existing Excel file that you target. That means that you aren't going to use this method to poke new values into an existing spreadsheet, or add sheets to an existing workbook. Compare that to PROC EXPORT DBMS=XLSX, which allows you to update an existing workbook by targeting just one sheet.
  • My example code works perfectly on the SAS University Edition! Simply change the destination file to be a location that SAS can write to -- for example, file="/folders/myfolders/example.xlsx".

If you want to learn more about the new ODS destinations in SAS 9.4 (which include HTML5, EPUB, POWERPOINT, and EXCEL), watch my interview and demo with David Kelley, R&D manager for ODS at SAS:

Post a Comment

Format your data like a social media superstar

In my industry of data and computer science, precision is typically regarded as a virtue. The more exact that you can be, the better. Many of my colleagues are passionate about the idea, which isn't surprising for a statistical software company.

But in social media, precision is a stigma -- especially when applied to the number of followers or connections that you have. Do you have so few connections that it can be represented as an exact number? Well, I wouldn't go bragging about that!

For example, let's look at this new LinkedIn joiner (blurred to protect his identity). As of this writing he has only -- and exactly -- 15 connections! (For the record, I consider this guy to be a rising star; I'm sure that his connections will skyrocket very soon.)

LinkedIn newcomer
Compare this to a more seasoned networker, shown below. LinkedIn won't tell us how many connections he has; perhaps they are beyond measure. We can see only that he has 500 or more LinkedIn connections. It might be 501 or it might be 500 million. It doesn't matter, according to LinkedIn. All you need to know is that this guy is a highly sought-after connection.

Let's create a SAS format to count connections, LinkedIn-style. It's simple: for cases of 500 or more, the label should be "500+". For fewer than 500, the label will be the embarrassingly precise actual number.

libname library (work); /* "library" is automatically searched for formats */
proc format lib=library;
 value linkedin    
  500 - high ='500+'
  /* all other values fall through to actual number */
/* test data */
data followers;
  length name $ 40 followers 8 displayed 8;
  format displayed linkedin.;
  infile datalines dsd;
  input name followers;
  displayed = followers;
Chris Hemedinger, 776
Kevin Bacon, 100543
Norman Newbie, 3
Colleen Connector, 499

Here's the result. Notice how the "displayed" value acts as sort of an equalizer among the super-connected. Once you've achieved a certain magnitude of connections, you're placed on par with all other "superstars".

Social sites like Instagram and Twitter operate on a different scale. While they still sacrifice precision when displaying a large number of "likes" or "followers", they do at least present a ballpark number that shows the magnitude of the activity. For example, instead of showing the exact follower count for Ronda Rousey (public figure, film star, MMA champ, and daughter of an experienced SAS presenter), Instagram simply truncates the number to the thousands and adds a "K".

To achieve the same in SAS, we can rely on a PICTURE format. This format contains the templates for what a number should look like, plus the multipliers to apply to get to the figure we want to display. Here's an example program, which I repurposed from the BIGMONEY example in SAS documentation.

proc format lib=library;
picture social (round)
 1E03-<1000000='000K' (mult=.001  )
 1E06-<1000000000='000.9M' (mult=.00001)
 1E09-<1000000000000='000.9B' (mult=1E-08)
 1E12-<1000000000000000='000.9T' (mult=1E-11);
/* test data */ 
data likes (keep=actual displayed);
format actual comma20.
 displayed social.;
 do i=1 to 12;
  displayed = actual;

Here's the result:

As you can see, the "displayed" values show you the magnitude of big "likes" in a cool-but-not-so-eagerly-precise way.

Here's my complete test program if you want to try it yourself. Happy networking!

Post a Comment

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