BookmarkSubscribeRSS Feed
sas_new
Calcite | Level 5

Hi everyone,

Here i just want to include the code i have in some macro variable into the macro.  i am getting some error when i try this.

How can i include this statement within this macro.

%let x=%nrstr(%do i=1 %to 3; data _null_;run; %end;);

%macro mm;

&x;

%mend mm;

%mm;

when i try this i am getting error "statement is not valid or not used in proper order"

Thanks in advance,

Deen

10 REPLIES 10
Tom
Super User Tom
Super User

I do not think you can do that.  If your code did not include macro control statements it should work.

How about creating a sub macro and then passing in the name of the submacro?

%macro doloop;

%do i=1 %to 3; data _null_;run; %end;

%mend doloop;

%let x=doloop;

%macro mm;

%&x ;

%mend mm;

options mprint;

%mm;

data_null__
Jade | Level 19

It won't work that way because %DO needs to be compiled.  You would need to make the value of X also a macro and you need to esacpe the % signs with %% in %NRSTR.

HOWEVER:  I cannot see how your code would be useful except to produce a Rube Goldberg machine. 

What are you trying to do?

sas_new
Calcite | Level 5

Thanks Tom and data _null_;

My input is one macro variable. That macro variable will contain some macro code.

i have to include that code into my macro and also i will write some code for execution.

Thanks,

Deen

Tom
Super User Tom
Super User

data_null_ was asking what your actual application for this technique is.

Perhaps if you explain what you want to be able to do that currently think could have been done by this technique someone can see another way to solve the actual problem.

You can go right by make three left turns,  but usually it is easier to just turn right.

sas_new
Calcite | Level 5

Once again thanks a lot TOM,

Thanks for your valuable suggestion.

%let trt_cnt=2;

%let trt1_cnt=2;

%let trt2_cnt=3;

%let trt1_1=a;

%let trt1_2=b;

%let trt2_1=c;

%let trt2_2=d;

%let trt2_3=e;

%macro mtest;

data testfn;    

stop; run;

   

%do p=1 %to &trt1_cnt;          

     %do q=1 %to &trt2_cnt;              

          data test;                  

               set input;                    

               var1="&&trt1_&p";                    

               var2="&&trt2_&q";              

          run;                        

          data testfn;                    

               set testfn test;              

          run;                       

     %end;    

  %end;

%mend mtest;

if the trt_cnt =3 then i have to add one more loop. here i am trying to generate the loop dynamically.

if my trt_cnt=3,    

%do p=1 %to &trt1_cnt;          

%do q=1 %to &trt2_cnt;              

%do k=1 %to &trt3_cnt;              

     data test;                  

          set input;                    

          var1="&&trt1_&p";                    

          var2="&&trt2_&q";                    

          var3="&&trt3_&k";                   

     run;                        

     data testfn;                    

          set testfn test;              

     run;                         

%end;          

%end;    

%end;

For that i assigned that macro code into one macro variable then I try to execute them within that macro.

For me that macro codes generating successfully, I can’t able to execute them within the macro or any other macro.

I did the code like below:

%let _return_trtid=2;

%macro mnew;    

%let code=;    

%let code= %str(data test;);       

%do _k=1 %to &_return_trtid;        

%let code=  &code %str(_VAR&_k="%nrstr(&&)%str(trt)%nrstr(&)%str(_l&_k)";);           

%end;    

%let code= &code %str(run;);    

%do _k=1 %to &_return_trtid;        

%if &_k=1 %then %let _trt_codes=%nrstr(%do) %str(_l&_k=1) %nrstr(%to) %str(&&_lcnttrt&_k; ) %str(&code)  %nrstr(%end;);        

%else %let _trt_codes=%nrstr(%do) %str(_l&_k=1) %nrstr(%to) %str(&&_lcnttrt&_k; ) %str(&_trt_code)  %nrstr(%end;);        

%let _trt_code=%str(&_trt_codes);    

%end;    

%put &_trt_code;    

&_trt_code    

%mend; %mnew;

In log:

_trt_code = “%do _l2=1 %to &_lcnttrt2;  %do _l1=1 %to &_lcnttrt1;  data test; _VAR1="&&trt&_l1"; _VAR2="&&trt&_l2"; run;  %end; %end; “

Its giving error when i Include _trt_code within the macro. I hope this may clear for you understand my problem.

Thanks,

DeeN

Tom
Super User Tom
Super User

Let me see if I can translate the code into english.

Looks like you have a list of treatment codes and are trying to loop over them.

Personally I am not that fond of making a series of macro variables when the information can be maintained in a single variable.

Your list of treatment codes could be recorded into a single macro variable using two different delimiters. If we use space and slash as the delimiters we could store your example as:

%let treatments=a b/c d e;

%let ngroups=2;

%let maxtrt=3;

Then you seem to want to generate a SAS dataset with these treatment codes.

You should be able to do that with a data step and not need to worry about macro logic at all.

data treatments;

   array trt $ trt1-trt&maxtrt ;

  do i=1 to &ngroups;

     call missing(of trt(*));

     do j=1 to &maxtrt;

        trt(j)=scan(scan("&treatments",i,'/'),j,' ');

     end;

     output;

   end;

   drop i j ;

run;

sas_new
Calcite | Level 5

Many thanks TOM,

Final i got the results with this approach.

%macro mtst;

%let trtid1=ID001;

%let trtid2=ID004;

%let trtid3=ID001a;

%let trtcnt=3;

%let trtlist=ID001,ID004,ID001a;

proc sort data=trtdef out=test;    

by trtid;    

where trim(left(trtid)) in ( %do i=1 %to &trtcnt;     "&&trtid&i"  %end; );

run;

data test1;    

length _cnt 8. _kl $200.;    

set test;    

if index(codes,'|') then do;    

_cnt=countw(codes,'|');    

do _i=1 to _cnt;    

_kl=scan(codes,_i,'|');   

output;    

end;   

end;    

else do;     _kl=codes; output;   

end;

run;

proc sort data=test1;    

by trtid;

run; data

%do i=1 %to &trtcnt;    

trtid&i(keep=&&trtid&i)

%end; ;    

set test1;

%do i=1 %to &trtcnt;    

length &&trtid&i $200.;    

if trim(left(trtid))="&&trtid&i" then do;        

&&trtid&i=_kl;        

output trtid&i;    

end;

%end;

run;

proc sql noprint;    

create table test2 as select %do i=1 %to &trtcnt-1; &&trtid&i, %end; &&trtid&i     from %do j=1 %to &trtcnt-1; trtid&j, %end; trtid&j;

quit;

%mend mtst;

%mtst;

Thanks for all your support to get this done TOM.  

Thanks

DeeN

data_null__
Jade | Level 19

Can you post a sample of the data in TRTDEF?

sas_new
Calcite | Level 5

TRTID     CODE

ID001     a|b|c

ID004     x|y

    

Thanks,

DeeN

data_null__
Jade | Level 19

I created a TRTDEF data set like this....

data trtdef;

   input (TRTID CODES)(:$20.);

   cards;

ID001     a|b|c

ID004     x|y

ID001a    a|e|f

;;;;

   run;


And I ran it through the code you posted to create data set TEMP2....

Obs    ID001    ID004    ID001a

   1      a        x        a

   2      b        x        a

   3      c        x        a

   4      a        y        a

   5      b        y        a

   6      c        y        a

   7      a        x        e

   8      b        x        e

   9      c        x        e

  10      a        y        e

  11      b        y        e

  12      c        y        e

  13      a        x        f

  14      b        x        f

  15      c        x        f

  16      a        y        f

  17      b        y        f

  18      c        y        f


Is this data set the file product your seek?  Also, if this is the output you want what do you do with it?

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 10 replies
  • 1209 views
  • 3 likes
  • 3 in conversation