next up previous
Next: Checking for duplicate by-variable Up: Writing frequently-used code as Previous: Merging macros


Hash-merging without having to type

See section 12.2 for how to use hashes to efficiently merge small datasets into large ones. Here I describe a macro that does it without typing.

This macro consists of three separate macros. The two small ones are called %enquote and %sepbycommas. They accept space-separated lists of variable names and print out, in the first case, that list with double-quotes around each name, separated by commas, and, in the second case, just the variable names separated by commas. If you provide

permno date ret

to the first macro, it will return

``permno'',''date'',''ret''

And the second will return

permno,date,ret

The macro that does the actual work, %hashmerge, just prints out the data step that does the hash merge.

%macro sepbycomma(varlist);             
    %let delim=%str( );
    
    %let outputvar=%qscan(&varlist,1,&delim);
    %let i=2;
    %do %while(%length(%qscan(&varlist,&i,&delim)) GT 0);
        %let varhere=%qscan(&varlist,&i,&delim);
        %let outputvar=&outputvar,&varhere;
        %let i=%eval(&i + 1);
        
        %end;
    &outputvar
    %mend;

%macro enquote(varlist);             
    %let delim=%str( );
    
    %let outputvar=''%qscan(&varlist,1,&delim)'';
    %let i=2;
    %do %while(%length(%qscan(&varlist,&i,&delim)) GT 0);
        %let varhere=%qscan(&varlist,&i,&delim);
        %let outputvar=&outputvar,''&varhere'';
        %let i=%eval(&i + 1);
        
        %end;
    &outputvar
    %mend;

            
%macro hashmerge(largeds, smallds, byvars, extravars, outds);
    data &outds;
        call missing(%sepbycomma(&extravars));
        if _n_=1 then do;
         declare hash h(dataset:''&smallds'');
         h.defineKey(%enquote(&byvars));
         h.defineData(%enquote(&extravars));
         h.defineDone();
         end;
     set &largeds;
     if h.find()=0;
    run;

    %mend;



Andre de Souza 2012-11-19