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!
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.
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
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?
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.
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.
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;
I see where it is wrong. Thanks a lot!
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.
http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a003167025.htm
Cheers from Portugal.
Daniel Santos @ www.cgd.pt
Hi Daniel, thanks for the extension. I realized this issue when I explored along Tom's hints.
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;
oh, this procedure is really handy. Thanks!
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.