Skip to content

Macro Variable Manipulation Demonstration

Chris Swenson edited this page Nov 14, 2020 · 1 revision

As mentioned in the paper, it is possible to use all 5 of the above macro variables in one piece of code. Below is code that demonstrates this usage. To try the program, first download the required SAS macro programs from this repository and set up a autocall library. Open SAS and set the autocall library options. Next, copy the following program and paste it into the same SAS session. Finally, run the code in blocks and review the output.

/********************************************************************************
   BEGIN PROGRAM HEADER
 ********************************************************************************

    Project:    SAS Global Forum
    Name:       MacroGen_Sample.sas
    Author:     Chris Swenson
    Created:    2012-03-02

    Purpose:    Generate a master table for each measure, including all
                categorical variables from all historic tables within a measure
                for a specific list of patients.

    Macros:     ObsMac    - Used to convert the list of measures desired into
                            macro variables in order to loop through each library.
                VarMac    - Used to dynamically set the libraries to different
                            physical locations.
                IntoList  - Used to create a list of patient IDs to filter on.
                TableVars - Used to set the tables to loop through.
                SetVars   - Used to select only character variables in each table.
                CheckLog  - Used to check the log for issues and stop processing
                            if any issues arise.

 ********************************************************************************
   END PROGRAM HEADER
 ********************************************************************************/


/********************************************************************************
   Parameter Setup
 ********************************************************************************/

/* Identify measures to run */
data project;
    infile datalines dsd;
    format name $5.;
    input name $;
/* BCS = Breast Cancer Screening */
/* COL = Colorectal Cancer Screening */
/* DM = Diabetes Mellitus */
datalines;
BCS
COL
DM
;
run;

/* Set parameters for library locations and years to include */
data paths;
    infile datalines dsd;
    format type $15. path $25.;
    input type $ path $;
datalines;
drive,H:
base,temp
data,files
start_year,2009
end_year,2010
;
run;

/* Set patient list */
data patients;
    infile datalines dsd;
    format patient_id $5.;
    input patient_id $;
datalines;
X1
X3
X5
;
run;


/********************************************************************************
   Generate Macro Variables
 ********************************************************************************/

/* Set measures to macro variables */
%ObsMac(project, name, project);

/* Set library parameters to macro variables */
%VarMac(paths, type, path);

/* Generate list of patients to keep */
%IntoList(patients, patient_id, patient_list, sepby=QQC);

/* Set the drive value to the WORK directory, for the purposes of this demo */
%let drive=%sysfunc(pathname(work));


/********************************************************************************
   Generate Master Tables
 ********************************************************************************/

/* Run each code */
%macro ProjectLoop;

    %local p project t table;
    %do p=1 %to &PROJECTCNT;

        %let project=&&PROJECT&P;
        %put NOTE: Processing project &PROJECT....;

        /* As a part of this demo, create the directories we need */
        %local user_xwait user_xsync;
        %let user_xwait=%sysfunc(getoption(xwait));
        %let user_xsync=%sysfunc(getoption(xsync));
        option noxwait xsync;
        %sysexec mkdir "&DRIVE.\&BASE.\&PROJECT.\&DATA";
        option &USER_XWAIT &USER_XSYNC;

        /* Set library for project */
        libname &PROJECT "&DRIVE.\&BASE.\&PROJECT.\&DATA";      /* <-- Project name and path parameters */

        /* Generate dummy tables */
        %do d=2008 %to 2012;
            data &PROJECT..year_&D(drop=i);
                format patient_id $5. result $25.;
                do i=1 to 5;
                    patient_id=compress('X' || put(i, 8.));
                    if i in (1, 4) then result='Screened';
                    else result='Not screened';
                    number=rand('uniform');
                    output;
                end;
            run;
        %end;

        /* Set tables in library to macro variables, filtering
           for tables between the start and end years */
        %TableVars(
              &PROJECT
            , table
            , where=input(compress(memname, '', 'kd'), 4.) 
              between &START_YEAR and &END_YEAR                 /* <-- Start/end years */
        );

        %do t=1 %to &TABLECNT;

            %let table=&&TABLE&T;
            %put NOTE: Processing table &TABLE....;

            /* Generate a list of character variables */
            %SetVars(&PROJECT..&TABLE, varlist, type=LIST, vtype=C);

            /* Add source and keep only character variables */
            data _temp;
                format Source $32.;
                set &PROJECT..&TABLE;
                where patient_id in (&PATIENT_LIST);            /* <-- Patient list */
                source="&TABLE";
                keep source &VARLIST;                           /* <-- Variable list */
            run;

            /* Append to master */
            proc append base=&PROJECT..Master data=_temp;
            run;

            %put NOTE: Processing table &TABLE complete.;

        %end;

        /* Use CheckLog to review and end the program if necessary */
        %Checklog(pm=E, sound=E);
        %if &ISSUES>0 %then %return;

        proc datasets library=work memtype=data kill nodetails nolist;
        quit;

        %put NOTE: Processing project &PROJECT complete.;
        %put ;

    %end;

%mend ProjectLoop;

%ProjectLoop;