简体   繁体   中英

How to use the && macro variable in SAS

I'm working with SAS and I have to create some macro variables within a DO loop. This is a portion of my code:

%if &dsempty888=0 %then %do;
    data _null_;
    set freq_&&var&i;
        if &&var&i=888888888 then do;
            call symput("cont8_&&var&i",percent);
        end;
    run;
%end;
%if &dsempty888=1 %then %do;
    %let cont8_&&var&i=0;
%end;

%if &dsempty999=0 %then %do;
    data _null_;
    set freq_&&var&i;
        if &&var&i=999999999 then do;
            call symput("cont9_&&var&i",percent);
        end;
    run;
%end;
%if &dsempty999=1 %then %do;
    %let cont9_&&var&i=0;
%end;


%if &dsempty444=0 %then %do;
    data _null_;
    set freq_&&var&i;
        if &&var&i=444444444 then do;
            call symput("cont4_&&var&i",percent);
        end;
    run;
%end;
%if &dsempty444=1 %then %do;
    %let cont4_&&var&i=0;
%end;

This code is inside another DO loop that run from i=1 to &end . With this my macro variables cont4_&&var&i cont8_&&var&i cont9_&&var&i are costantly overwrited...and they become unuseful outside of their loop. I tried to name them &&cont4_&&var&i for example. But clearly SAS doesn't solve the macro. In practice inside of the loop the macro are created, but I don't know how to call them when I need outside.

How can I fix?

Thanks in advance.

You've got a lot of issues here, so let's simplify this some. Here's a very simplified example. This, for example, does something:

%let var1 = age;
%let var2 = height;
%let var3 = weight;

proc freq data=sashelp.class noprint;
  tables age/out=freq_age;
  tables height/out=freq_height;
  tables weight/out=freq_weight;
run;


%macro get_freqs(var_count=);
  %do i = 1 %to &var_count.;
      data _null_;
        set freq_&&var&i;
        call symput("cont4_&&var&i",percent);
      run;
  %end;
%mend get_freqs;

%get_Freqs(var_count=3)

But now if we do

%put cont4_&&var&i;

Of course it doesn't work, since &i has no meaning. So instead we replace that with, say, 1:

%put cont4_&&var1;

Now we get something. But we don't get anything useful, do we, just the variable name. But - at least that's something!

Now we don't really need the second & there, right?

%put cont4_&var1;

But we need a & before this to use the macro variable:

%put &cont4_&var1;

But now we get a warning message, CONT4_ not resolved . Okay, let's add a second & to delay the resolution of the macro variable until &var1 is resolved.

%put &cont4_&var1;

Well, that helped, now it says CONT4_AGE not resolved . Why not? We used call symput to define that, right?

The problem is scoping . call symput probably scoped it locally, meaning it was defined in the macro but not outside of the macro. For this we use call symputx and give it a global scope.

%macro get_freqs(var_count=);
  %do i = 1 %to &var_count.;
      data _null_;
        set freq_&&var&i;
        call symputx("cont4_&&var&i",percent,'g');
      run;
  %end;
%mend get_freqs;

This tells SAS that I want &cont4_age to be defined outside of the macro. Otherwise it will only be available locally - inside the macro - and will get cleaned up.

Now, this works:

%put &&cont4_&var1;

But if you wanted to iterate over &i again, it's a bit more complex. That's because you need to delay those ampersands multiple times, and allow several passes.

Here's what works:

%macro iterate_i(var_count=);
  %do i = 1 %to &var_count.;
    %put &&&&cont4_&&var&i.;
  %end;
%mend iterate_i;

%iterate_i(var_count=3);

Why do we need four & s? Well, we need to get to &&cont4_&var1 , right? That happens in the first pass. Here are the three passes:

&&&&cont4_&&var&i -> &&cont4_&var1 -> &cont4_age -> 5.26...

Each pass, the following happens:

  • && -> & (and save for next pass)
  • & -> resolve macro variable

So, that's how you'd iterate over those. You can of course explicitly specify at any level the macro variable - so all of these work:

%let i=1;
%put &&&&cont4_&&var&i;
%put &&cont4_&var1;
%put &cont4_age;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM