Monday, February 12, 2018

Michael A. Raithel's SAS Limerick #4

SAS Programming Professionals,


Something to make you smile while you write programs today:

    I once inherited a SAS macro so intense,

    That its logic just did not make sense,

    I thought that MLOGIC, SYMBOLGEN, and MPRINT,

    Would show me where the macro's logic ultimately went,

    But the resulting log was too overly dense.

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

Hack 7.6 Determining SAS Files Types by Their Extensions




SAS Programming Professionals,

Did you know that you can quickly determine the nature of SAS files when viewing them on your operating system via their file extension? 

Knowing what SAS file type corresponds to the file extension can be handy when combing through directories in Windows Explorer or in native Linux.  Here are the file extensions:

Easy:

·        .sas      - SAS program
·        .log      - SAS log
·        .lst      - SAS list
·        .sas7bdat - SAS data set

More Obscure:

·        .sas7bndx - SAS index
·        .sas7bcat - SAS catalog
·        .sas7bvew - SAS view

Most Obscure:

·        .sas7bmdb - SAS MDDB
·        .sas7bitm - SAS Itemstore

You can get a list of SAS file extensions for you particular environment by accessing the SAS online documentation and viewing the SAS Companion document for that operating system.  For example, if you were using Windows, you would access the SAS 9.4 Companion for Windows and search for “file extension”.  That will net you a web page with a very nice table of SAS file extensions.  Check it out!

Best of luck in all your SAS endeavors!

---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

Monday, February 5, 2018

Michael A. Raithel's SAS Limerick #3

SAS Programming Professionals,


Something to make you smile while you write programs today:

    In my SAS logs nothing could be rarer,

    Than to find a SAS WARNING or ERROR,

    Because I buy books from SAS Press,

    To keep my syntax from being a mess,
   
    Every one of my logs is a good news bearer.


Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

Hack 7.5 Creating SAS Data Sets with Another Operating System’s Data Representation




SAS Programming Professionals,

Did you know that you can create a SAS data set in another operating system's internal data representation format? 

For example, you might be running SAS on Windows and want to create a UNIX SAS data set in a Windows directory for later delivery to a UNIX system.  You can do this using either the OUTREP data set option or the OUTREP LIBNAME option.  Here are examples of both options:

options msglevel=I;

/* Two examples of using the OUTREP LIBNAME option */

libname UNIXDATA "C:\TEMP\UNIXDATA" outrep=hp_ux;

/* 1. Creating a new SAS data set in the "Foreign" data library */

data UNIXDATA.class;
set  sashelp.class;
run;

proc contents data=UNIXDATA.class;
run;

/* 2. Copying a SAS data set to the "Foreign" data library */
proc copy in=sashelp out=UNIXDATA noclone;
      select prdsale;
run;

proc contents data=UNIXDATA.prdsale;
run;

/* 3. Using the OUTREP data set option */

libname UNIXDATA clear;

libname UNIXDATA "C:\TEMP\UNIXDATA";

data UNIXDATA.orsales(outrep=hp_ux);
set  sashelp.orsales;
run;

proc contents data=UNIXDATA.orsales;
run;

In the first LIBNAME OUTREP option example, the newly created CLASS data set will be in HP-UX format, even though it is stored on a Windows directory.  Check out the Data Representation field in the CONTENTS listing.

In the second LIBNAME OUTREP option example, the PRDSALE data set will be in HP-UX format.  But, notice that when the COPY procedure is executed, SAS normally "CLONE"-s the format of the input data set to the output data set.  So, you need to use the NOCLONE option for the new data set (UNIXLIB.PRDSALE) to be in HP-UX format.

The final example illustrates how you can code OUTREP data set option to store UNIXDATA.ORSALES as a UNIX SAS data set, even though it is stored in a Windows directly--as specified in the LIBNAME statement.

Note that with the MSGLEVEL=I option enabled, you will see the following type of message in your SAS log:

INFO: Data file UNIXDATA.CLASS.DATA is in a format that is native to another host, or the file encoding does not match the session encoding. Cross Environment Data Access will be used, which might require additional CPU resources and might reduce performance.


That message lets you know that you have, indeed, been successful in storing a SAS data set in a foreign host’s data representation.  Good job!

Best of luck in all your SAS endeavors!

---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

Monday, January 29, 2018

Hack 7.4 Creating a Temporary Flat File with the TEMP Option of the FILENAME Statement




SAS Programming Professionals,

Did you know that you can use the TEMP option of the FILENAME statement to create a temporary flat file?

You can write to or read from that flat file as long as the FILENAME remains assigned.  I often use the TEMP option to build a program within a program and then execute it.  Here is an example:

/****************************************************/
/* Beginning of the IDENTIFY SAS Macro.             */
/****************************************************/
%MACRO IDENTIFY(SASLIB,DIRNAME);

********************************************************************;
* Pipe the names of data files to the SAS System for processing.   *;
********************************************************************;
filename dircmd pipe "dir /b &DIRNAME\*.txt";

********************************************************************;
* Temporary file to hold the READFLAT SAS Macro call statements.   *;
********************************************************************;
filename holdmacs TEMP;

********************************************************************;
* Process each specific file name, dropping unneeded ones. Format *;
* SAS READFLAT Macro calls for valid data files.                  *;
********************************************************************;
data _null_;

length outline $100;

file holdmacs;

infile dircmd missover length=length;

input bigline $varying200. length;

outline = '%READFLAT(' || "&SASLIB" || ',' || "&DIRNAME" || '\' || trim(left(bigline)) || ');';

put outline;

run;

********************************************************************;
* Include holdmacs, which is now a series of READFLAT SAS Macro    *;
* invocations. This will execute Process_Flat_Files.sas once for   *;
* each “.txt” flat file found in the target data directory.        *;
********************************************************************;
%INCLUDE holdmacs;

/****************************************************/
/* End of the IDENTIFY SAS Macro.                   */
/****************************************************/
%MEND IDENTIFY;

In this very busy example, the first FILENAME statement directs SAS to perform the DIR command on a data directory and output the names of the files in that directory when the DIRCMD filename is accessed. 

The second FILENAME creates a temporary flat file named HOLDMACS

The DATA step reads the data set names passed to the DIRCMD filename statement.  Then, it formats a line of code that is an invocation of the %READFLAT macro.  It then writes that line to the HOLDMACS temporary file.  After the data step has completed executing, the HOLDMACS temporary file looks something like this:

%READFLAT(Q:\data,Q:\system1\datadir\store22_01212015.txt);
%READFLAT(Q:\data,Q:\system1\datadir\store55_01212015.txt);
%READFLAT(Q:\data,Q:\system1\datadir\store64_01212015.txt);
%READFLAT(Q:\data,Q:\system1\datadir\store97_01212015.txt);

So, when the %INCLUDE statement executes, it includes the four macro invocations stored in HOLDMACS, executing them one after another.  Neat trick, eh?  I would bet that you can find a clever use for a TEMP flat file too!

Best of luck in all your SAS endeavors!

---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

Michael A. Raithel's SAS Limerick #2

SAS Programming Professionals,


Something to make you smile while you write programs today:

      In Cary NC at the SAS Institute,

    The staff is most clever and highly astute,

    For, seemingly out of thin air,

    They generate world-class software,

    So that companies their BI can compute.

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

Monday, January 22, 2018

Hack 7.3 Concatenating Multiple Directories in a LIBNAME Statement




SAS Programming Professionals,

Did you know that you can concatenate multiple directories together in a LIBNAME statement?

Most programs have a 1-to-1 correlation between a LIBNAME statement and a SAS data library.  However, it doesn’t need to be that way in real life!  You can have multiple directories specified in a LIBNAME statement.  Consider this example:

libname ctemp ("c:\temp", "c:\temp\usertemp");

data class;
set  ctemp.class(where=(sex="M"));

run;

proc sort data=class out=ctemp.sortedmales;
      by descending age;
run;

libname ctemp list;

In the example, we are concatenating two directories (c:\temp and c:\temp\usertemp) together to form the CTEMP SAS data library.  When you use “CTEMP” as the first level of a two-level SAS data set name, SAS will search first c:\temp, and then c:\temp\usertemp for that SAS data set.  If there is a SAS data set with the same name in both libraries, SAS uses the first one it comes across.

Check out the log from this program:

1    libname ctemp ("c:\temp", "c:\temp\usertemp");
NOTE: Libref CTEMP was successfully assigned as follows:
      Levels:           2
      Engine(1):        V9
      Physical Name(1): c:\temp
      Engine(2):        V9
      Physical Name(2): c:\temp\usertemp
2
3    data class;
4    set  ctemp.class(where=(sex="M"));
5
6    run;

The note highlighted in yellow, above shows that SAS recognizes the concatenation of the two directories to form one SAS data library.

NOTE: There were 10 observations read from the data set CTEMP.CLASS.
      WHERE sex='M';
NOTE: The data set WORK.CLASS has 10 observations and 5 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds

The note highlighted in yellow, above shows that SAS read the CLASS data set from the CTEMP directory.  In fact, CLASS is located in c:\temp\usertemp, which is the second directory in the concatenation.

7
8    proc sort data=class out=ctemp.sortedmales;
9        by descending age;
10   run;

NOTE: There were 10 observations read from the data set WORK.CLASS.
NOTE: SAS sort was used.
NOTE: The data set CTEMP.SORTEDMALES has 10 observations and 5 variables.
NOTE: PROCEDURE SORT used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds

The note highlighted in yellow, above shows that SAS stored the SORTEDMALES data set in the CTEMP directory.  By default, SAS stores all new data sets in c:\temp, which is the first directory in the concatenation.


11
12   libname ctemp list;
NOTE: Libref=   CTEMP
      Scope=    DMS Process
      Levels=   2
        -Level 1-
      Engine=   V9
      Physical Name= c:\temp
      Filename= c:\temp
        -Level 2-
      Engine=   V9
      Physical Name= c:\temp\usertemp
      Filename= c:\temp\usertemp

In the example above, the LIST option on the LIBNAME statement is used to list the attributes of the CTEMP libref; including the directories that are concatenated together.

As long as you understand the rules of the road, (SAS processes the first data set it finds with a specific name when traversing the concatenated files; and SAS writes new data sets to the first directory in the concatenation) concatenating directories together for a single SAS data library can be very useful!

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

https://tinyurl.com/y83aleb4

Best of luck in all your SAS endeavors!

---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

Michael A. Raithel's SAS Limerick #1

SAS Programming Professionals,


Something to make you smile while writing your programs today:

    At the corporate headquarters of a premier hotel,

    Managers had all of their data locked up in Excel,

    So they hired a SAS programmer named Miles,

    Who had SAS Access Interface to PC Files,

    Now they thoroughly understand their clientele.

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 


Monday, January 15, 2018

Hack 7.2 Capturing the Values of Windows Environmental Variables




SAS Programming Professionals,

Did you know that you can capture the name and value of Windows environmental variables with SAS?

Environmental variables are a class of variables created by the operating system to store values used by a wide variety of programs.  For example, the TEMP variable holds the value of the directory that all programs should use when creating temporary files.  On the Windows 7 workstation I am currently using, that value is C:\Users\Michael\AppData\Local\Temp.

Here is a very straight-forward program you can use to identify the Windows environmental variables and their values:

filename enviovar pipe 'set' lrecl=1024;

data work.xpset;

infile enviovar dlm='=' missover;

length name $ 32 value $ 100;

input name $ value $;

run;

proc print noobs;
title1 "Windows Environmental Variables for My Workstation";
run;
If you take a moment to run that program, you will find a fascinating array of environmental variables available to you. You can see the directory common programs are stored in, the path to your home directory, the number of processors your computer has, the processor architecture, the user name, and the directory where the user profile is stored.

You can capture and then use the Windows environmental variables in your SAS programs where you need to identify something particular to a Windows workstation or PC.  Or, you might choose to dump them into a flat file as a means of documenting the exact system that you were running SAS programs on—say in a clinical trials environment.  The Windows environmental variables are there for the using.  So, go ahead and use them!


The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers
https://tinyurl.com/y83aleb4

Best of luck in all your SAS endeavors!

---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7