Monday 17 January 2011

FCMP: BKf_GateKeeper Function


By Eli Kling using sas V9.2/Base

From time to time the developers in Cary make an addition that excites even sas–dinosaurs like myself. Not everyone sees the potential of, or even the need for proc FCMP. However, I think it signals a major change in the way sas is used and developed and opens the door for cutting edge statistical modelling also on platforms that have ‘only’ Base/Stat/Graph.

The obvious challenge I first tackled as a learning exercise was calculating the Benjamini-Hochberg FDR correction to a vector of p-values. It was the focus of my dissertation a thousand years ago. I will discuss it in a following entry.

Good practice calls to first check that the vector passed in is appropriate and abort the processing otherwise. The BKf_GateKeepr function below checks that all the elements of a vector contain values between 0 and 1 and returns 0 for OK and 1 for Failed. If the check failed it also puts a message in the log.

As I intend to expand the functionality of this function I included a ‘Check’ switch indicating what check to perform. In the version below only ‘PVALUE’ is programmed.

You will also notice that the sas editor has a problem to correctly colour the key words. I am sure that will be fixed in later versions.

proc delete data=sasuser.BusinessKenLibrary; run;
options cmplib=sasuser.BusinessKenLibrary;

proc fcmp outlib=sasuser.BusinessKenLibrary.dev;

/* RC=BKf_GateKeeper(Vector,Check)
 a utility to be used to check vector inputs
 Input Vector - the vector of values to check
       Check  - what to check
       pvalue: verify all values between 0 and 1
 output RC - 0 = passed check
             1 = failed check
*/
 function BKf_GateKeeper(vector(*),Check$);
 put "check" Check;
 N=dim(Vector);
 RC=0;
  if Upcase(Check)="PVALUE" then do;
    do i=1 to N;
       if not(0<=vector[i]<=1) then RC=1;
      end;
    if RC=1 then put "<< BK Values Gate Keeper: A vector of pvalues was expected but at least one value was not in the interval [0,1]. Note, it might have been a missing value. >>";
   end;
 return(RC);
 endsub;

run;


/********/
/* Test */
/********/
data test;
 * Array parameters to subroutine calls must be temporary arrays;
 array a(3) _temporary_;
 a[1]=5;
 a[2]=0.01;
 a[3]=0.96;
 RC=BKf_GateKeeper(a,"Pvalue");
 run;
proc print;run;
/*****************************************************************/
/* Code End                                                      */
/*****************************************************************/