Monday, August 22, 2016

Summertime and The Writin’ is Easy


SAS Programming Professionals, 

Summertime and the writin’ is easy!  Clients are on vacation, managers are on vacation, users are on vacation, colleagues are on vacation, and the office is quiet.  Nice and quiet. Maybe just a little too quiet!

In many offices, there is a lull in the programming workload as people enjoy the warmer weather and head out for vacations, three-day weekends, and summer holidays.  The result of this happy exodus is fewer deadlines and less pressure on your work hours during the summer months.  So, what can you do when the programming workload diminishes?

You can outline and write the draft of a SAS technical paper for SAS Global Forum 2017; that’s what you can do!

The SAS Global Forum 2017 Call for Content is open between now and October 17th. 
http://www.sas.com/en_us/events/sas-global-forum/sas-global-forum-2017/program/sessions.html#call-for-content

Next year’s conference is actively looking for content in five formats:

  • Breakout Sessions – Get insights on the in-depth aspects of SAS software, including programming techniques, technical features, and innovative and practical applications. They can also be strategies and best practices about how to apply SAS to solve industry-specific challenges.
     
  • Hands-On Workshops – Get hands-on experience through a demonstration that you direct for 45 minutes. Hands-On Workshops (also known as HOW) are intended to help attendees learn how to use the features of SAS or JMP®.
     
  • Quick Tips – Perfect for beginners and experts alike to share quick tips and tricks, and useful nuggets of programming techniques that make jobs easier. A Quick Tip session should last 10 minutes or less and cover one concept in a concise and practical way
     
  • E-Posters – Here’s a perfect opportunity to present your solution or idea in a more relaxed environment and in a visually informative way. A greener alternative to traditional posters, e-posters allow you to transport digital posters in your pocket
     
  • Table Talks – Facilitated by one lead user in an informal, small-group conversational setting (max. of 20 participants), these sessions will not require a formal paper to be submitted. A limited number of sessions will be selected, and each may be offered multiple times.

Do you have an area of SAS expertise, a great programming methodology, or a clever SAS programming technique that you would like to write about and present?  If so, then compose a draft of the paper during the current programming lull and submit it to SAS Global Forum 2017.
 
If you have not previously submitted a SAS technical paper to a conference, then you may consider following steps: 

  • First determine if you have novel content to offer or a fresh perspective on doing something that is tried-and-true.  The best way to do this is to search previous conference papers to see if your topic has already been covered to excess.  Here is a link to previous years’ SAS Global Forum proceedings:  http://support.sas.com/events/sasglobalforum/previous/online.html
     
  • Thoroughly research your topic using SAS online documentation, previous conference papers, and other types of research papers that apply to your subject matter.  You want to make sure that your own paper covers the most up-to-date facets of the topic you are going to be presenting.
     
  • Create a draft of your paper.  Your draft should have the following sections:
     
    • Abstract – This is a concise paragraph or two that specify the programming “problem” and the solution your paper is presenting.
       
    • Introduction – This section provides a more detailed discussion about the programming problem and your solution.  It also introduces how the content of the body of the paper will be laid out.
       
    • Body of paper – This part is composed of multiple sections that provide the detailed explanations of your programming methodology, code, tip, etc.
       
    • Conclusion -- One or more paragraphs that summarize what has been discussed in the body of the paper.
       
    • Disclaimer – A standard boiler-plate disclaimer concerning the contents of your paper, SAS trademarks, and other trademarks must be included at the end of your paper.  See the author’s guidelines for the latest wording.
       
    • References – A list of references you used in researching your paper.   Your readers can access these references for additional information on the material presented.
       
    • Acknowledgements – A paragraph that thanks the people who helped you or who provided guidance during your research or writing of the paper.
       
    • Contact Information – Of course, you will want people to contact you either to heap praise upon the clever insightfulness of your paper or to ask questions.  So, provide an email address that they can use.
       
  • Submit your proposal to the conference by accessing this link:  http://www.contentet.com/SASGF2017/
     
  • Enjoy having put together a cogent treatment of a SAS topic and anticipate getting good news from the SAS Global Forum 2017 staff in October.

Okay, so the Call for Content does not actually require that an entire draft of your paper be submitted in order for it to be considered.  However, you should take advantage of this respite in your programming workload to get the research and writing heavy lifting done now.  You are not going to have the luxury of having so much time on your hands once the summer is over and everybody is back in their offices.
 
Summertime and the writin’ is easy!  That makes it a perfect time to outline, draft, and submit a paper to SAS Global Forum 2017.
 
Or, of course; you could just go to the beach!
 
Best of luck in all your SAS endeavors!
 
----MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
http://www.amazon.com/Michael-A.-Raithel/e/B001K8GG90/ref=ntt_dp_epwbk_0

Monday, August 15, 2016

Hack 3.17 Maintaining Relative Order During PROC SORT

SAS Programming Professionals,

Did you know that you can maintain the relative order of observations in a BY group during a sort?  You can do so by using the EQUALS option on the PROC SORT statement. 

This concept is easier to illustrate than it is to describe, so let’s consider the SASHELP.CLASS data set that is already sorted by NAME.


We would like to have the data set sorted by SEX, but keep the NAMEs in alphabetical order within SEX.  So, we would code:

proc sort data=sashelp.class out=class equals;
by sex;
run;

…which nets the following:


Note that the resulting SAS data set is sorted by SEX and that the relative order of NAME (in alphabetical order) has been preserved.  The EQUALS option is handy for when you already have an established relative order within observations that you want to maintain after sorting by the variables in your BY statement.


Best of luck in all your SAS endeavors!

----MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)

Excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

I plan to post each and every one of the hacks in the book to social media on a weekly basis.  Please pass them along to colleagues who you know would benefit.

Friday, August 5, 2016

Hack 3.16 Keeping Track of SAS Data Set Updates with Audit Trails

SAS Programming Professionals,

Did you know that you can have SAS keep an audit trail of all of the updates made to a SAS data set? 

This is particularly handy if you need to determine who updated a SAS data set at any given time for a security review or a data integrity audit.  The audit trail file allows you to track when particular observations were added, modified, or deleted.  You may even be able to fashion your own update roll-back program from the audit file.

Creating an audit trail file for a SAS data set is easily done via the DATASETS Procedure.  Here is an example:

proc datasets library=cperm noprint;
      audit orsales;
      initiate;
run;
quit;

Executing the code, above, results in a SAS audit file named orsales.sas7baud being built in the CPERM SAS data library.  When updates are made to the orsales SAS data set, entries are made to the attendant orsales SAS audit file.

You can determine the variables available in your audit file by using PROC CONTENTS with the TYPE=AUDIT data set option.  Here is an example:

proc contents data=cperm.orsales(type=audit);
run;

The resulting Alphabetic List of Variables and Attributes looks like this:

Alphabetic List of Variables and Attributes
#
Variable
Type
Len
Format
Label
4
Product_Category
Char
25

Product Category
5
Product_Group
Char
25

Product Group
3
Product_Line
Char
20

Product Line
7
Profit
Num
8
12.2
Profit in USD
6
Quantity
Num
8
6.
Number of Items
2
Quarter
Char
6

Quarter
8
Total_Retail_Price
Num
8
12.2
Total Retail Price in USD
1
Year
Num
8
4.
Year
9
_ATDATETIME_
Num
8
DATETIME19.

14
_ATMESSAGE_
Char
8


10
_ATOBSNO_
Num
8


13
_ATOPCODE_
Char
2


11
_ATRETURNCODE_
Num
8


12
_ATUSERID_
Char
32




The variables beginning with _AT are the audit trail variables.  Two of the most important are _ATDATETIME_ and _ATUSERID_ which hold the date/time an observation was updated and the user ID of the person who updated the observation, respectively.

Once a SAS data set with an audit trail is updated, you can examine the specifics of the change by using PROC PRINT with the TYPE=AUDIT data set option:

proc print data=cperm.orsales(type=audit);
run;

You can use other SAS procedures, such as PROC REPORT and PROC SQL to print out the SAS audit file, too.

There is much, much more to discuss on this topic, and the SAS technical writers handle it with their usual thoroughness in the SAS online documentation on support.sas.com.  Check it out!

Best of luck in all your SAS endeavors!

----MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)

Excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

I plan to post each and every one of the hacks in the book to social media on a weekly basis.  Please pass them along to colleagues who you know would benefit.

Tuesday, July 26, 2016

Hack 3.15 Keeping Specific SAS Files During Mass Deletions

SAS Programming Professionals,

Did you know that you can delete all SAS files in a given SAS data library _EXCEPT_ those that you specifically list in the SAVE statement using PROC DATASETS? 

Think of PROC DATASETS’ SAVE statement as a kind of KEEP statement for SAS files instead of for SAS variables.  Consider this example:

proc datasets library=raithlib;
      save FaveCDList FaveMovielist;
run;
quit;

That program deletes the dozen or so SAS data sets, catalogs, etc. in my RAITHLIB SAS data library, leaving my two favorite SAS data sets FaveCDList and FaveMovieList behind.

If I had a catalog with the same name as one of the two aforementioned SAS data sets, I would simply include a “/memtype=data” to the end of the SAVE statement, above, and that catalog would be history, but my SAS data sets wouldn’t be!

Best of luck in all your SAS endeavors!

----MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)

Excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

I plan to post each and every one of the hacks in the book to social media on a weekly basis.  Please pass them along to colleagues who you know would benefit.

Monday, July 18, 2016

Hack 3.14 Jump Starting PROC REPORT

SAS Programming Professionals,

Did you know that you can get PROC REPORT to “jump start” itself?

The breadth and scope of the SAS programming language makes it a challenge to remember the exact syntax of every procedure.  So, many of us use shortcuts whenever we can find them.  One such shortcut is the LIST option in PROC REPORT.  The LIST option directs SAS to write the PROC REPORT code to the log… without line numbers! 

So, this SAS code:

proc report data=sashelp.class list noexec;
run;

…produces this log entry:

1    proc report data=sashelp.class list noexec;
2    run;

PROC REPORT DATA=SASHELP.CLASS LS=96  PS=54  SPLIT="/" CENTER ;
COLUMN  Name Sex Age Height Weight;

DEFINE  Name / DISPLAY FORMAT= $8. WIDTH=8     SPACING=2   LEFT "Name" ;
DEFINE  Sex / DISPLAY FORMAT= $1. WIDTH=1     SPACING=2   LEFT "Sex" ;
DEFINE  Age / SUM FORMAT= BEST9. WIDTH=9     SPACING=2   RIGHT "Age" ;
DEFINE  Height / SUM FORMAT= BEST9. WIDTH=9     SPACING=2   RIGHT "Height" ;
DEFINE  Weight / SUM FORMAT= BEST9. WIDTH=9     SPACING=2   RIGHT "Weight" ;
RUN;

We can now cut-n-paste the PROC REPORT code from the log into a SAS program and edit it to make a perfect report for our project.  Not bad, eh?

Wondering about the NOEXEC option?  Not surprisingly, that option tells SAS NOT to execute the REPORT procedure and create a report.  Might as well save a few CPU cycles whenever we can! 

Best of luck in all your SAS endeavors!

----MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)

Excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

I plan to post each and every one of the hacks in the book to social media on a weekly basis.  Please pass them along to colleagues who you know would benefit.

Friday, July 15, 2016

Hack 3.13 Inserting Blank Lines in PROC PRINT Output

SAS Programming Professionals,

Did you know that you can make PRINT procedure output more readable by inserting blank lines?

If you are still tethered to using good old PROC PRINT to create reports for your users, then you know how crowded some of the listings can be when you have a lot of data to print.  The BLANKLINE option of PROC PRINT allows you to insert a blank line every N rows.  Here is an example:

proc sort data=sashelp.class out=class;
      by sex;
run;

proc print noobs data=class sumlabel blankline=5;
     
by sex;

sum weight height;

label sex = "Gender";

title1 "Class Roster By Gender";

run;

The BLANKLINE option on our PROC PRINT statement specifies for SAS to insert a blank line after every five lines of output.  The result looks, in part, like this:

Gender=F
Name
Age
Height
Weight
Alice
13
56.5
84.0
Barbara
13
65.3
98.0
Carol
14
62.8
102.5
Jane
12
59.8
84.5
Janet
15
62.5
112.5

Joyce
11
51.3
50.5
Judy
14
64.3
90.0
Louise
12
56.3
77.0
Mary
15
66.5
112.0
Gender

545.3
811.0

Notice the nice blank line between Janet and Joyce.  I like to set the value to either 10 or 20 on those rare occasions when I am creating long listings with PROC PRINT.  I wonder what value you will end up using.

Best of luck in all your SAS endeavors!

----MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)

Excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

I plan to post each and every one of the hacks in the book to social media on a weekly basis.  Please pass them along to colleagues who you know would benefit.

Monday, July 11, 2016

Hack 3.12 Identifying Duplicate Variable Values with PROC MEANS

SAS Programming Professionals,

Did you know that you can use the MEANS procedure to identify duplicate variable values in a SAS data set?

This can come in very handy when you need to QC a SAS data set where you know that a particular variable is supposed to have unique values, or where the combined values of a set of variables is supposed to be unique.

Here is an example:

%MACRO IDENTIFY_DUPES(LIBREF=, DSNAME=, VARLIST=);

proc means data=&LIBREF..&DSNAME nway noprint missing;
      class &VARLIST;
      output out=duplicates(drop=_type_ rename=(_freq_ = 
                 duplicate_count)
                  where=(duplicate_count > 1) ) sum=;
run;

proc print data=duplicates noobs label;
      var &VARLIST duplicate_count;

title1 "Duplicate Values in the &DSNAME SAS Data Set";

title2 "Duplicate Count for Variables: &VARLIST";

label duplicate_count = "Duplicate Count";

run;

%MEND IDENTIFY_DUPES;

%IDENTIFY_DUPES(LIBREF=SASHELP, DSNAME=prdsal2,
    VARLIST=country county prodtype year);

This macro accepts three parameters:

·        LIBREF – The libref of the SAS data library that contains our target data set
·        DSNAME – The name of our target SAS data set
·        VARLIST – The list of variables whose combination we want to check for duplicate values.

The MEANS procedure specifies our target SAS data set by using the LIBREF and DSNAME macro variables.  The NWAY option states that we only want statistics for the unique combinations of CLASS variables.  NOPRINT suppresses that pesky, unneeded list output.  The MISSING option directs PROC MEANS to consider missing values when computing statistics.  We use the list of variables in the &VARLIST macro in the CLASS statement, so the procedure only calculates statistics for those specific variables.

In the OUTPUT statement, we rename PROC MEAN’s _FREQ_ variable to DUPLICATE_COUNT, and only keep the summarized observations whose DUPLICATE_COUNT is greater than 1.  The SUM= option directs PROC MEANS to summarize the number of observations it finds for each combination of variables and store that number in the _FREQ_ variable.

The PRINT procedure creates a report of duplicate variable values surfaced by the MEANS procedure.

Here is part of the resulting list output from the PROC PRINT:



Duplicate Values in the prdsal2 SAS Data Set
Duplicate Count for Variables: country county prodtype year
Country
County
Product Type
Year
Duplicate
Count

Canada

FURNITURE
1995
576

Canada

FURNITURE
1996
576

Canada

FURNITURE
1997
576

Canada

FURNITURE
1998
576

Canada

OFFICE
1995
576

Canada

OFFICE
1996
576

Canada

OFFICE
1997
576

Canada

OFFICE
1998
576



If you are concerned about duplicate variable values in your SAS data sets, this is the macro for you!

Best of luck in all your SAS endeavors!
----MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)

Excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

I plan to post each and every one of the hacks in the book to social media on a weekly basis.  Please pass them along to colleagues who you know would benefit.