Thursday, February 4, 2010

Scheduler for asynchronous script processing

As a IT programmer, we have to handle scripts on many platforms, e.g. DOS, ksh.
Due to limited functionality of script language, it is not easy to schedule many scripts to let them run step by step.

With SAS, we can take it easily.
I strongly recommended SAS programmer should use SYSTASK and WAITFOR to control the script processing.
By contrast, X is suitable for interactive task.

Below are codes from SAS online doc:

systask command "sas myprog1.sas" taskname=sas1;
systask command "sas myprog2.sas" taskname=sas2;
systask command "sas myprog3.sas" taskname=sas3;
waitfor _all_ sas1 sas2 sas3;

Tuesday, January 19, 2010

PIPE mode in external file functions

To get the output of shell command within SAS, we have to resort to PIPE.
Generally the job is using DATA step input/output.
We can also use external file funcitons to handle it, although it is more complex.


%let command = hostname;

data _null_;
length value $ 20;
rc = filename('myfile', "&command", 'PIPE');
fid = fopen('myfile', 'S');
rc = fread(fid);
rc = fget(fid, value, 20);
rc = fclose(fid);
rc = filename('myfile');

put "Command output:" value;
run;

%let filerf=myfile;
%let rc = %sysfunc(filename(filerf, &command, pipe));
%let fid = %sysfunc(fopen(&filerf, S));
%let rc = %sysfunc(fread(&fid));
%let rc = %sysfunc(fget(&fid, value, 20));
%let rc = %sysfunc(fclose(&fid));
%let rc = %sysfunc(filename(filerf));

%put Command output: &value;

Tuesday, December 15, 2009

Automatic index variable _i_ in DO OVER

Recently SAS-L started an new topic "Do over can't be nested?".
I think it is very helpful for anyone who is interested with DO OVER.

quote:
Paul Choate says:
A little history lesson - in the 5.18 manual page 44 chapter 4 it says: "You can process more than one array in a DO OVER group if the arrays have the same number of elements and the same index variable."

It later says: "... (DO OVER) arrays use the automatic index variable _I_."
unquote


* Sample code;
data _null_;
array arra a1-a10 (0 1 2 3 4 5 6 7 8 9);
array arrb b1-b10 (10 11 12 13 14 15 16 17 18 19);

_i_=3;
put _i_= arra= arrb=;

_i_=6;
put _i_= arra= arrb=;

do over arra;
put "Start: " _i_=; * _i_ will be initialized to 1;
do over arrb;
put _i_= arra= arrb=;
end;
put "End: " _i_=; * ;
end;
run;

Thursday, December 3, 2009

RUN-group processing in SAS/Graph procedures

In SAS packages, some procedures may support RUN-group processing, e.g. Proc CATALOG, Proc DATASETS in SAS/Base, Proc GPLOT, Proc GCHART in SAS/Graph and Proc REG in SAS/STAT, etc.

Basically, RUN-group processing is used to perform task interactivly and efficiently without restarting the procedure. It is very intersting that ONLY the ones in SAS/Graph can reset or cancel global and local statements, BY statements, WHERE statement.

* Sample Code;
proc sort data=sashelp.class out=class;
by name;
run;
proc gplot data=class;
where;
by;
title "All Subjects";
plot height*weight;
run;
where sex='M';
by name;
title "Male";
plot height*weight;
run;
where sex='F';
by;
title "Female";
plot height*weight;
run;
quit;

For more information, please read SAS/GRAPH Processing: RUN-Group Processing.

Wednesday, November 25, 2009

Read and sort in one step - Hash object tip

In SAS world, the classical way to process raw file is to read it into SAS dataset and then sort it. With SAS9 Hash object in DATA step, we can make an all-in-one step.

* Hash sample - read and sort raw data;
data _null_;
/* Declare hash object and key and data variable names */
if _N_ = 1 then do;
declare hash h(ordered:'A');
rc = h.defineKey('key');
rc = h.defineData('key','value');
rc = h.defineDone();
end;

/* Read key and data values */
infile datalines eof=eof;
input key value $;

/* Add key and data values to hash object */
rc = h.add();

return;
eof: rc = h.output(dataset:"ordered");
cards;
1 value1
3 value2
2 value3
;

Actually, it is only one little tip of Hash object.
We must never forget that the main functionality of Hash object is to quickly and efficiently store, search, and retrieve data based on lookup keys.

Tuesday, November 17, 2009

To list ALL using PRELOADFMT

The option PRELOADFMT is available only with Proc MEANS, Proc REPORT and Proc TABULATE.
To include all ranges and values of the user-defined formats in the output, the 3 Procs give out different usages.
Below are the samples for that.

proc format;
value $sex
'M' = 'Male' 'F' = 'Female' 'O' = 'Other';
run;

proc means data=sashelp.class completetypes mean;
format sex $sex.;
class sex / preloadfmt;
var height;
run;

proc report data=sashelp.class completerows nowd;
format sex $sex.;
column sex height;
define sex / group preloadfmt;
define height / analysis mean;
run;

proc tabulate data=sashelp.class ;
format sex $sex.;
class sex / preloadfmt;
var height;
tables sex*height*mean / printmiss;
run;

Monday, November 16, 2009

Logical expression play differently between %eval and DATA step

When programming macro, It is helpful to complete it in a DATA step and then port the code to macro. However, not all tricks in DATA step work in macro world.

Below is one tip for that:

data _null_;
do a=1 to 4;
if 1 < a < 3 then put a= "is between 1 and 3";
end;
run;

%macro test();
%put Wrong example:;
%do a=1 %to 4;
%if %eval(1 < &a < 3) %then
%put a=&a is between 1 and 3;
%end;

%put Correct example:;
%do a=1 %to 4;
%if %eval(1 < &a and &a < 3) %then
%put a=&a is between 1 and 3;
%end;
%mend;

%test()