Tuesday, December 28, 2010

Send Seasons Greetings - in SAS

On this festive season, you can send cool animated images to your loved ones - a la SAS way!!! Here is how you do it.
  • Add a filename email with the required to/cc/bcc id's.
  • Include the HTML img tag and give the following source path as shown below.
  • You can also hyperlink it to your website if you might want to...

TO=("getpramod.r@tgmail.com" )
From =("getpramod.r@gmail.com")
SUBJECT ="Season's Greetings"
CT= "text/html" ;

FILE mail1;
PUT ' Wish You a Merry Chirstmas!!! ';
PUT 'http://2.bp.blogspot.com/_HV9w9_0BEgE/TRmqNR8gtlI/AAAAAAAAAd0/sHaxYi5XzFc/s320/merry_christmas_animated.gif';
PUT 'And a Happy New Year!!! ';
PUT 'http://4.bp.blogspot.com/_HV9w9_0BEgE/TRmqfRCHBwI/AAAAAAAAAd4/MEX-HTubTwI/s320/HappyNewYearAll.gif';

Execute the above code and lo-behold!! You get an animated gif in your mail body as shown below:

Wish You a Merry Chirstmas!!!
And a Happy New Year!!!

Wish you all a Merry Christmas and a Prosperous New year!!!

Friday, December 10, 2010

Accessing Unix server in windows explorer

There has always been a debate between using a GUI-based, windows-freindly FTP client like WinSCP and a conventional telnet client like PuTTY. One party says that its Easy to use and doesn't need any unix knowledge to perform any operations; and the other says that one needs to have such roboust telnet clients to "keep in touch" with the commands/syntax and accept the fact that not everything in the world is "Winowized".

I did a google fight between these two and here is the winner :

Anyway, before i digress too much, let me show you a intersting way to access your UNIX servers from windows without downloading any FTP client or a telnet client:
  • Open the Internet Explorer and type the following in the address bar and hit enter:
  • ftp://<user-name>:<password>@<server-name>
  • Now you would be able to see your unix home directory in your windows explorer if you are using IE 6. If you are using a IE 8, then click on Page and click on Open FTP Site in Windows Explorer. You may be prompted for a user id and password again.
  • Now save this link in you favourites and next time you want to login, you could just open a windows explorer and login using your credentials.

Monday, December 6, 2010

Resolve vs Symget

Symget function enjoys lot more amount of pulicity and usage as compared to the resolve function, though the later one actually is (at least according to me..) more efficient, powerful and more flexible! (Guess am becoming more sentimental these days..)

Having this in mind, i tried searching about some articles on resovle function in google but in vain. There are lot more number of articles and examples of symget usage and call execute functions as compared to the resolve functions which accomplishes both these functionality.

Resolve function resolves the value of the text expression during the data step execution. It can reslove the value of a macro variable (like symget) and also expand the macro invokation (somewhat similar to call execute, just that it expands the macro and doesn't execute it...)

I've illustrated below, a few simple examples of various uses of Resolve funtion.

Illustration 1: Macro variable resolution in a datastep (similar to symget)

data t;
dt = symget(sysdate9.);
dt1 = resolve('&sysdate9.');

Both the variables in the above datastep returns a character variale of length 200 each having the value of the current date in date9. format.

Illustration 2: Mutiple macro variable resolution in a datastep (extention from symget)

data t;
dt = symget('sysdate9')||' '||symget('systime');
dt1 = resolve('&sysdate9. &systime.');

We can also use resolve function to resolve multiple macro variables (which is unavailable in symget).

Illustration 3: Expansion of a Macro using resolve

%macro min;
select min(age)
from sashelp.class
%mend min;

%macro m(i);
proc sql;
create table tab12 as
select *
from sashelp.class
where age=&i;
%mend m;

data _null_;
call execute(resolve('%m(%min)'));

In the above example, I use resolve function along with the call execute function which would expand the macro invokation twice (though a single resolve function is being used). Thus, the above data step does a call execute once and resolves the %m which inturn takes the arguement as %min which in turns expands. So the result code would be like this, which is shown in the log:

NOTE: CALL EXECUTE generated line.

1 + proc sql;
1 + create table tab12 as select * from sashelp.class where age=select min(age) from sashelp.class;
1 + quit;

NOTE: Table WORK.TAB12 created, with 2 rows and 5 columns.

Illustration 4: Conditional execution and execution in a data step loop

%macro sql(i,minage,maxage);

%if &i=&minage %then %do;
   Proc Sql Noprint;
   Create table tab as
   select *
   from sashelp.class
   where age = &i

%else %if &i=&maxage %then %do;
   select *
   from sashelp.class
   where age = &i;

%else %do;
   select *
   from sashelp.class
   where age = &i
%mend sql;

proc sql noprint;
select min(age), max(age) into : minage, : maxage
from sashelp.class;

data _null_;
do i=11 to 16;
  call execute(resolve('%sql('||i||',&minage,&maxage)'));

In the above example, I'm trying to append multiple datasets which are created out of sashelp.class (for each age values). Here, I'm trying to execute the %sql macro in a datastep loop, and passing both the macro variable and the data step variable as the macro parameters.

This example also shows how to conditionally execute the macro variable based on the parameters passed.

I've pasted below the log message for the above code. Also note that the iteration number is printed at the begining of the every iteration's resolution.

NOTE: CALL EXECUTE generated line.

1 + Proc Sql Noprint;
1 + Create table tab as select * from sashelp.class where age = 11
2 + UNION ALL select * from sashelp.class where age = 12
3 + UNION ALL select * from sashelp.class where age = 13
4 + UNION ALL select * from sashelp.class where age = 14
5 + UNION ALL select * from sashelp.class where age = 15
6 + UNION ALL select * from sashelp.class where age = 16;
6 + Quit;

NOTE: Table WORK.TAB created, with 19 rows and 5 columns.

Thursday, December 2, 2010

Blogger's paradise!

Recently i was invited to join a website named http://www.sas-x.com/ by  Tal Galili

I suggest everyone to subscribe to this feed. It has the aggregation of many big names in SAS blogging like  Chris Hemedinger, Mark Stevens, Jared Prins, Rick Wicklin, and many more!!

Its a privilege that my blog was added to this website...

All the best Tal!