Help with double macro

Accepted Solution Solved
Reply
Super Contributor
Posts: 412
Accepted Solution

Help with double macro

Good morning Everyone,


I have a code that contains a macro like the one below and I now want to add a macro cover all the code. So it will be macro inside macro.

In the target code, the overall macro will let the value 2 change.

The tricky part for me is that the original macro output will be used in many step afterward and it is quite difficult to combine the 2 macro into 1 like %macro ALL(value=,x=,multiple=).

Thank you for your help.

HHC

data have;
  input time level;
  datalines;
1   5
2   2
3   8
4   10
5   12
6 2
7 22
8 5
9 7

;run;


data havenew; set have;
level=level+  2;run;

%macro odd_multiple(x=, multiple=);
data sample_&x; set havenew;
if time=&x;
if time=&x then level=level*&multiple;
run;

data havenew; set havenew sample_&x;               /*Here I update the new file with new row*/
run;
%mend;

%odd_multiple (x=1,multiple=2);
%odd_multiple (x=3,multiple=3);
%odd_multiple (x=6,multiple=4);

proc sort data=havenew; by time;run;

PROC EXPORT
data=havenew
outfile="C:\exportfile.csv"
dbms=dlm
replace;
delimiter=';';
run;

Below is what I want:

%macro ALL (value=);

data havenew; set have;

level=level+  &Value;run;

%macro odd_multiple(x=, multiple=);
data sample_&x; set havenew;
if time=&x;
if time=&x then level=level*&multiple;
run;

data havenew; set havenew sample_&x;               /*Here I update the new file with new row*/
run;
%mend;

%odd_multiple (x=1,multiple=2);
%odd_multiple (x=3,multiple=3);
%odd_multiple (x=6,multiple=4);

proc sort data=havenew; by time;run;

PROC EXPORT
data=havenew
outfile="C:\exportfile &value _&x _multiple..csv"
dbms=dlm
replace;
delimiter=';';
run;

%mend;

%All (value=2);

%All (value=3);


Accepted Solutions
Solution
‎10-09-2013 04:08 PM
Super User
Super User
Posts: 7,050

Re: Help with double macro

In general you can just pass in the macro values from outer macro environment to the inner macro environment via the macro call. Frequently I find it most useful to use the same parameter names on both macros as this makes it clearer what value is being passed.

%macro odd_multiple(x=, multiple=);

...

%mend odd_multiple;

%macro all(value=,x=, multiple=);

...

%odd_multiple(x=&x, multiple=&multiple);

...

%mend all;

View solution in original post


All Replies
Super User
Posts: 19,815

Re: Help with double macro

I don't understand your question.

Super User
Super User
Posts: 7,050

Re: Help with double macro

It should be easy to create a new macro that calls the old one.  It will be easier if you place the macro definitions first and then start your programming that will call the macros.  It is not clear what you want but you code structure could be.

%macro odd_multiple(x=, multiple=);

data havenew ;

  set havenew;

  output;

  if time=&x then do;

    level=level*&multiple;

    output;

  end;

run;

%mend;

%macro all(value=,xlist=,mlist=);

data havenew;

  set have;

  level=level+ &value;

run;

%do i=1 %to %sysfunc(countw(&xlist,%str( ));

  %odd_multiple (x=%scan(&xlist,&i,%str( )),multiple=%scan(&mlist,&i,%str( )));

%end ;

%mend all ;

data have ;

.....

%all(value=2,xlist=1 3 6,mlist=2 3 4);


proc export

....

Super Contributor
Posts: 412

Re: Help with double macro

Thank you again for your help, Tom.
Your double macro is what I am looking for.

I will try to implement it.

HHC

Super Contributor
Posts: 412

Re: Help with double macro

Hi Tom,

Could you suggest a "longer" form of double macro code your wrote before? I mean "longer" code helps me understand it step by step better.

Also, if the format of the %all allow me to list combination of variable one by one is more helpful to me, such as:

%all(value=2, xlist=1,mlist=2);

%all(value=2, xlist=3,mlist=2);

....

Thank you,

HHC

Solution
‎10-09-2013 04:08 PM
Super User
Super User
Posts: 7,050

Re: Help with double macro

In general you can just pass in the macro values from outer macro environment to the inner macro environment via the macro call. Frequently I find it most useful to use the same parameter names on both macros as this makes it clearer what value is being passed.

%macro odd_multiple(x=, multiple=);

...

%mend odd_multiple;

%macro all(value=,x=, multiple=);

...

%odd_multiple(x=&x, multiple=&multiple);

...

%mend all;

Super Contributor
Posts: 412

Re: Help with double macro

Hi Tom,

Many thanks for help me out again.

I think I got it.

HHC

data have;
  input time level;
  datalines;
1   5
2   2
3   8
4   10
5   12
6 2
7 22
8 5
9 7

;run;

data have1; set have; run;

%macro odd_multiple(x=, multiple=);
data havenew_&x ;
  set havenew;
  if time=&x;
  if time=&x then do;
    level1=level*&multiple;
  end;
run;

data have1; set have1 havenew_&x;run; *add to the file;
%mend;

%macro all(value=,x=,multiple=);
data havenew; set have;
level2=level + &value;
run;

%odd_multiple (x=&x,multiple=&multiple);

%mend;

%all (value=2,x=1,multiple=2);

%all (value=3,x=2,multiple=10);

Super Contributor
Posts: 412

Re: Help with double macro

Hi Tom,

I got the double macro you told me.

However sometime thing is too big to keep track.

That's why I post have a post on forum to ask for help with another approach.

I appreciate it if you could have a look at my question in the link below:
https://communities.sas.com/message/184141#184141

Thank you and have a nice day.

HHC

Super User
Super User
Posts: 7,050

Re: Help with double macro

Are you trying to make multiple files? How many?  One for each level of VALUE? or X ? or MULTIPLE?

For each iteration do you want to modify from he original file or modify the previously modified file.

Most of what it looks like you are doing is possible in a data step without any macro coding.

data want ;

  set have ;

* Keep the original values ;

  output;

* Iterate over selected values to increment level ;

  original_level = level;

  do value=2,3 ;

    level = original_level + value ;

    output ;

    select (time) ;

      when (1) do;

         level = level * 2 ;

         output;

      end;

      when (3) do;

         level = level * 3 ;

         output;

      end;

      when (6) do;

         level = level * 4 ;

         output;

      end;

      else;

    end;

  end;

run;

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 8 replies
  • 333 views
  • 3 likes
  • 3 in conversation