1
votes

I am struggling with how I can create output when I am using a macro do loop in SAS. In a regular data step, I can create the following dataset with variables i and var to be "printed" in the output window by doing:

data example;
    do i=1 to 4;
    var = 2+i;
    output;
run;

Which will create, in the output window,

Obs    i     var
  1    1       3
  2    2       4
  3    3       5
  4    4       6

Now, my issue is that I am using a macro do loop and can't seem to do the same as in a regular data step (i.e. can't get my result to show in the output window). The goal of my macro is to add "_new" to the end each variable name (A B C D) from the list, and then I need this to show up in the output window.

%let myvarlist=A B C D;

%macro create_new;
    %let mlength=%countlength(&myvarlist);
    %let suffix=new;

    %do n=1 %to &mlength;
        %let var_n=%qscan(&myvarlist,&n);
        %let my_new_varlist=&var_n._&suffix;
    %end;
%mend;
%create_new

The closest thing I could get that worked was putting %put &my_new_varlist; right before the %end statement, but this puts it in the log window. I tried inserting my do loop within a data step and then using a proc print but that didn't work.

The macro %countlength is a macro I use to count the number of variables in my list. The code for it is:

%macro countlength(char);
  %local num inputword;

  %let num=1;
  %let inputword=%qscan(&char,&num,%str( ));
      %do %while(&inputword NE);
          %let num=%eval(&num+1);
          %let inputword=%qscan(&char,&num,%str( ));
      %end;
  %eval(&num-1);

%mend;
2
I don't think there's a way to easily do it. You could create a data step and proc print it. I wonder what you're trying to do overall.Reeza
Yeah that's a very odd request. Why not just populate a table, and use your favorite method to print to the output screen afterwards?Robert Penridge

2 Answers

1
votes

I don't think the macro language alone can be used to write to output window, because that is not it's job. It's job (mostly) is to generate SAS code. However, SAS code can write to the output window. Perhaps:

data _null_ ;
  file print ;
  put "&my_new_varlist" ;
run ;

Suggest you look at Richard Devenzia's utility macro %seplist. It's a very nice approach to adding prefixes/suffixes/delimiters to lists. http://www.devenezia.com/downloads/sas/macros/index.php?m=seplist

0
votes

There are global macro symbol table and local macro symbol table, &num macro variable produced in countlength macro program is local macro variable, it will be drop from local table after countlength is finished to run, so &num could not be used for call macro program(create_new). Your code could be modified as:

%macro countlength(char);
  %let num=1;
  %let inputword=%qscan(&char,&num,%str( ));
      %do %while(&inputword NE);
          %let num=%eval(&num+1);
          %let inputword=%qscan(&char,&num,%str( ));
      %end;
  %global mlength;    
  %let mlength=%eval(&num-1);

%mend;

%let myvarlist=A B C D;

%macro create_new;
    %countlength(&myvarlist)
    %let suffix=new;
    %do n=1 %to &mlength;
        %let var_n=%qscan(&myvarlist,&n);
        %let my_new_varlist=&var_n._&suffix;
        %put &my_new_varlist;
    %end;
%mend;
%create_new

In addition, countw is SAS function to count word number. You could use directly.

%macro create_new;
    %let mlength=%sysfunc(countw(&myvarlist));
    %let suffix=new;

    %do n=1 %to &mlength;
        %let var_n=%qscan(&myvarlist,&n);
        %let my_new_varlist=&var_n._&suffix;
        %put &my_new_varlist;
    %end;
%mend;
%create_new

EDIT: If I understand your question correctly, maybe this is codes.

%let myvarlist=A B C D;
%macro create_new;
    %local mlength sufix n;
    %let mlength=%sysfunc(countw(&myvarlist));
    %let suffix=new;
    data want;
    %do n=1 %to &mlength;
        %let var_n=%qscan(&myvarlist,&n);
         my_new_varlist="&var_n._&suffix";
         output;
    %end;
    run;
%mend;
%create_new