DATA Step, Macro, Functions and more

a simple but tricky sas macro bug

Reply
Contributor
Posts: 20

a simple but tricky sas macro bug

dear all, I am learning SAS macro for my research recently and confronted a macro problem which looks like simple, but has been bothering me for couple of days.

The original data set looks like as following

a b

1 3

2 5

3 10

I need to transform the data to this form

Code:

bc1 bc2 bc3

3

    5

        10

I tried to use the attached code to accomplish this, but I got

bca

3

5

10

My code is as following,

Code:

%MACRO varlist(i=,content=);

dc&i=&content;

%MEND varlist;

data test;

input a b;

cards;

1 3

2 5

3 10

;

run;

data test1(drop=a b);

set test;

%varlist(i=a,content=b);

run;

Someone told me that the bug is due to the variable a is numerical. However, when I let a be strings, like "apple", "orange" and "banana", I still have the some problem. I guess it won't be very complicate to solve this bug, but I am struck with it. Thanks for you helps!

Trusted Advisor
Posts: 1,019

Re: a simple but tricky sas macro bug

data ab;

  input a b;

datalines;

1 3

2 5

3 10

run;

data want;

  array bc {3} bc1-bc3;

  set ab;

  bc{a}=b;

  drop a b;

run;

You don't need macro for this.

Super Contributor
Posts: 1,636

Re: a simple but tricky sas macro bug

If you don't have to use macro, you can try the code below:

data test;

input a b;

cards;

1 3

2 5

3 10

;

run;

options missing=' ';

data want(keep=b1-b3);

  set test;

  array _b(*) b1-b3;

  _b(a)=b;

  run;

  proc print;run;

options missing='.';

obs     b1    b2    b3

1      3

2            5

3                 10

Contributor
Posts: 20

Re: a simple but tricky sas macro bug

Thanks for you guys. This should solve me problem. Though I don't need macro now, I am still curious about why the macro does not work in the original code. Any hints?

Super User
Super User
Posts: 7,046

Re: a simple but tricky sas macro bug

Macro code just a code generation tool. In your case the macro generates DATA step code. THEN the data step runs.  So there is no way for the macro code to see much less react to changes in the value of variables inside of datasets.  In your example A and B are just text strings to the macro processor. 

Contributor
Posts: 20

Re: a simple but tricky sas macro bug

If so, the values of B should not be passed to macro. In this case, only A is treated as string and B seems working well. That is something confusing me.

Super User
Super User
Posts: 7,046

Re: a simple but tricky sas macro bug

But the VALUES of B were not passed to the macro.  The macro just generated the text "dca=b".  Because of where it was placed in the data step this was then interpreted by regular SAS as an assignment statement.

The same as if you just submitted the generated code without using the macro:

data test1(drop=a b);

set test;

dca=b;

run;

Contributor
Posts: 20

Re: a simple but tricky sas macro bug

I see where it is wrong. Thanks a lot!

Super Contributor
Posts: 474

Re: a simple but tricky sas macro bug

Tom's answer says pretty much all. I would just add this...

As said Macro SAS works mostly at compile time. That's where macro code/vars gets "solved".

So that's why there's no interaction with the run time phase, which comes next.

I say mostly, because you can actually "fiddle" with Macros at run time.

symput, symget, and other datastep macro functions allows you to manipulate Macro vars from the inside of the running datastep.

More on this here:

http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a003167025.htm

Cheers from Portugal.

Daniel Santos @ www.cgd.pt

Contributor
Posts: 20

Re: a simple but tricky sas macro bug

Posted in reply to DanielSantos

Hi Daniel, thanks for the extension. I realized this issue when I explored along Tom's hints.

Contributor
Posts: 25

Re: a simple but tricky sas macro bug

Hi tediest,

       I know Tom's answer solved your doubt. I am a newbie. Me too tried your code , you can get the result with the following code too.

data test;
input a b;
cards;
1 3
2 5
3 10
;
run;

proc transpose data = tst prefix= bc out =test1(drop= a _NAME_);
var b;
by a;
id a;
run;

proc print data = test1; run;

Contributor
Posts: 20

Re: a simple but tricky sas macro bug

oh, this procedure is really handy. Thanks!

Ask a Question
Discussion stats
  • 11 replies
  • 468 views
  • 0 likes
  • 6 in conversation