0
votes

I have a SAS program with a macro that will output a different list of variables based on the input criteria. For example, with %MACRO(OPTION1), I get three variables, but with %MACRO(OPTION2), I get four variables. The name of all of the variables is fixed, but it's just a matter of if they are created or not (based on the option).

How can I adjust the macro so that any option inputted by the user will still allow the macro to run? In other words, how can I tell it to ignore some variables if they don't exist.

Fortunately, I am not restricted to any specific procedure, but it would probably have to be either in a DATA step (macro language) or a PROC SQL statement (where clause or some other conditional statement).

1
There's no way to answer this treating the macro as a black box. You're going to need get an understanding of how the macro works and then post specific questions if you still have them.Jeff

1 Answers

2
votes

This is answerable in the general, as an approach to programming.

The first rule:

Use macro parameters explicitly when the amount of code is small.

This means, if you want to (say) do a PROC MEANS on something, but the variable differed, you could do:

%macro run_means(var=);
  proc means data=sashelp.class;
    var &var.;
  run;
%mend run_means;

%run_means(var=height);
%run_means(var=weight);

etc. Don't put some conditional logic in the macro, make them external. This includes lists of variables; make the whole list of variables parameters. Don't write them into your macro. If it's a long list, make it a macro variable in your main program, and pass that macro variable. Your macro itself should strive to accept what's given; today you have two sets of variables, tomorrow you might have three, or a slightly different set of one or the other. It's easier to change what you pass to the macro than to change the macro.

This concept will feel comfortable to folks used to object oriented programming, in particular the modular approach, although the separation of data is a bit different.

The second rule:

When substantial parts of a macro vary based on a parameter, separate that code into multiple macros.

In this case, let's say you have two things you want to do: run a PROC MEANS, or run a PROC FREQ, depending on if it's a character or numeric variable. Here, I suggest a general rule of not putting all of that into one macro. It's possible, but it's generally a bad idea. Adding to the previous macro, if you wanted to do this for sashelp.class, I'd do it like this:

%macro run_freq(var=);
  proc freq data=sashelp.class;
    tables &var.;
  run;
%mend run_freq;

%run_means(var=height);
%run_means(var=weight);
%run_freq (var=sex);

How you create these may be programmatic. A lot depends on what you're doing and how you're generating the code; and sometimes in the middle of your macro, you generate the value that determines which of the two things you do. I would still write the portion that varies as a separate macro, though; you can then add logic to call the appropriate macro, and allow it to be more legible.