Monday, February 13, 2017

Hack 4.12 Renaming Files and Directories from A DATA Step


SAS Programming Professionals,

Did you know that you can rename SAS data sets, SAS catalog entries, as well as OS directories and files in directory-based operating systems from inside of a SAS DATA step? 

The RENAME function lets you do exactly that!  It is great for SAS purists who do not want to use the X command or the CALL SYSTEM routine to “shell out” to the operating system to rename files and/or directories.  And, if you have PROC DATASET phobia, you can use the RENAME function to rename SAS files.

Here is a simple example:

data _null_;

rc = rename('c:\temp\test.pdf', 'c:\temp\old.pdf', 'file');

put "*****************";

put "the return code is: " rc;

put "*****************";

run;

The example above renames “test.pdf” to “old.pdf” in a DATA step.  The nice thing about the RENAME function that differentiates it from the X command or the CALL SYSTEM routine is that you get a return code that you can query to make sure that your rename worked.

Intrigued?  Well, then read more about it in the SAS online documentation on support.sas.com

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 6, 2017

Hack 4.11 Removing Leading and Trailing Blanks with the STRIP Function


SAS Programming Professionals,

Did you know that there is a function that will effortlessly strip off leading and trailing blanks from a character variable?

The aptly named STRIP function allows you to do just that and is a great replacement for the old TRIM(LEFT(character-variable)) construct many programmers used to use.

Here is an example of using the STRIP function:

data cars;
set  sashelp.cars;

car_statement = "The " || strip(make) ||
                   " " || strip(model)||
              " is a " || strip(type) ||
              ".";

run;

proc print noobs data=cars;                    
      var car_statement;
run;

Which produces, in part:

The Acura MDX is a SUV.
The Acura RSX Type S 2dr is a Sedan.
The Acura TSX 4dr is a Sedan.
The Acura TL 4dr is a Sedan.
The Acura 3.5 RL 4dr is a Sedan.
The Acura 3.5 RL w/Navigation 4dr is a Sedan.
The Acura NSX coupe 2dr manual S is a Sports.
The Audi A4 1.8T 4dr is a Sedan.
The Audi A41.8T convertible 2dr is a Sedan.

In the example, we are constructing variable CAR_STATEMENT by concatenating string constants and concatenating the variables MAKE (13 characters in length), MODEL (40 characters in length) and TYPE (8 characters length).  Without the STRIP function, there would be big gaps in CAR_STATEMENT because many of the MAKEs, MODELs, and TYPEs are not 13, 40, and 8 characters long, respectively.

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 30, 2017

Hack 4.10 Removing Leading and Trailing Blanks with the CATX Function


SAS Programming Professionals,

Do you know that you can quickly and easily remove leading and trailing blanks when concatenating character variables together?

If you were thinking “Ah yes, the CATS function!” then give yourself a prize!  However, this tip is really about the CATX function.

The CATX function removes leading and trailing blanks and inserts a separator between the variable values being concatenated.  (The CATS function only removes leading and trailing blanks).   This function is handy for building meaningful character variables from two or more variables—like building a full name from first name, middle name, and last name.

Here is an example:

data names;

firstname  = "       Francis";
middlename = "Scott         ";
lastname   = "   Key        ";

fullname = catx(" ", firstname, middlename, lastname);

run;

proc print noobs data=names;
run;

You can see that FIRSTNAME has leading blanks, MIDDLENAME has trailing blanks, and LASTNAME has both leading and trailing blanks.  The CATX function specifies that the separator should be a blank.  So, the result of the PROC PRINT is:

     firstname    middlename    lastname         fullname

     Francis       Scott         Key       Francis Scott Key

If you like the CATX function, check out its brothers, the CAT, CATT, and CATS functions!

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 23, 2017

Hack 4.9 Removing Blanks From Macro Variable Text


SAS Programming Professionals,

Did you know that the CALL SYMPUTX routine can save you keystrokes and lead to leaner, cleaner SAS programs? 

In the past, when we needed to load a SAS macro variable with a character string that might contain blanks, we would do the following:

call symput('MACROVAR',trim(left(charvar)));

This can be reduced by 12 keystrokes by using CALL SYMPUTX in the following manner:

call symputX('MACROVAR',charvar);

Think how happy your tired fingers will feel with a savings like that!

My older programs are littered with "trim(left)" CALL SYMPUT's and I would bet that yours are too.  I plan to replace mine as time and circumstance allows when I open my programs to address other issues.  How about you?

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 16, 2017

Hack 4.8 Putting Your SAS Programs to Sleep


SAS Programming Professionals,

Did you know that you can actually put your SAS programs to sleep?

The SLEEP function suspends execution of your SAS program (puts it to sleep) for the duration of time that you specify in the function.  This function comes in handy when you need to programmatically pause your SAS programs for various reasons.  One such reason is to wait for an asynchronous system event to occur before your SAS program continues.  For example, if you use an X statement to invoke an operating system command, you could put your program to SLEEP for the duration that it takes for that command to complete.

The general form of the SLEEP function is:  Q = SLEEP(N); …where:

·        Q = any SAS variable

·        N = the number of seconds to wait.  The maximum is 46 days!  See the documentation if you want to specify other intervals, such as micro-seconds.

Here is an example of the SLEEP function in action:

options noxwait noxsync xmin;

x '"C:\Program Files\Microsoft Office\Office11\excel.exe"';

data _null_;
  x=sleep(10);
run;

filename comma1 dde 'excel|system';

data _null_;
 file comma1;
 put '[open("D:\MCR\t_excel.xls")]';
run;

data _null_;
  x=sleep(10);
run;

…Other SAS code to populate the Excel spreadsheet…

The overall thrust of this example is to use DDE to open and populate an Excel spreadsheet from a SAS program.  First, we use the SAS X statement to send a command to Windows to open Excel.  Secondly, we put our program to sleep for 10 seconds in a DATA _NULL_ step to give Windows enough time to complete opening Excel.  Next, the FILENAME statement sets up our DDE “environment” and the second DATA _NULL_ creates our spreadsheet in the opened Excel program.  Then, we put our SAS program to sleep a second time to give Excel enough time to create the t_excel.xls spreadsheet in the opened Excel program in the aforementioned DATA _NULL_ step.

If you are tired of having your programs fail due to SAS-generated asynchronous tasks not completing on time, consider using the SLEEP function!

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 9, 2017

Hack 4.7 Increasing the Accuracy of Age Calculations with the YRDIF Function


SAS Programming Professionals,

Did you know that the YRDIF function can increase the accuracy of your age calculations?

The YRDIF function returns the number of years between two dates.  So, it can be useful in cases where you are looking for age, years in a study, duration of dosage, etc.  The format of the YRDIF function is:

               YRDIF(start-date, end-date, basis)

…where basis describes how SAS should calculate the difference between dates.  The most common basis is “ACT/ACT”, which specifies that SAS is to calculate YRDIF as the number of days that fall in 365-day years divided by 365 plus the number of days that fall in 366-day years divided by 366.  Here is an example:

data mybirthday;

     my_age_in_years = yrdif("27APR1975"d,today(),"ACT/ACT");

     label my_age_in_years = "My Current Age";

run;

proc print noobs label data=mybirthday;
run;

In the example, we determine the difference between my birth date and today’s date.  I entered a date literal for start-date and the TODAY() function for end- date, but I could have easily used two variables containing date values, instead.  The SAS listing looks like this:

My Current Age

   39.1534

Of course the year calculation is only as accurate as the information you feed into the YRDIF function.  If you are curious about other possible values for basis, look up the YRDIF function in the SAS Online Documentation on support.sas.com.

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

Tuesday, January 3, 2017

Hack 4.6 Determining The Dates of Major Holidays with the HOLIDAY Function


SAS Programming Professionals,

Did you know that the HOLIDAY function allows you to determine the date of major US and Canadian holidays? 

You simply supply the HOLIDAY function with the holiday keyword and the year, and it will return the SAS date value.  The syntax looks like this:

               HOLIDAY('holiday',year)

Here is an example that computes three holidays for the next ten years:

data future_holidays;

label year = "Year"
      mothersday= "Mothers Day"
      presidentsday = "Presidents Day"
      victoriaday = "Victoria Day"
      ;
format mothersday presidentsday victoriaday worddate.;

do year = 2015 to 2025 by 1;

mothersday = holiday("MOTHERS",year);
presidentsday=holiday("USPRESIDENTS",year);
victoriaday=holiday("VICTORIA",year);
output;
end;

run;

proc print noobs label;
run;

There are currently twenty-two holiday keywords for the HOLIDAY function.  You can read more about the HOLIDAY function, including all of the available holiday keywords, in the SAS online documentation on the support.sas.com web site.
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