DATA Step, Macro, Functions and more

Dynamic macro variable access

Reply
Occasional Contributor
Posts: 9

Dynamic macro variable access

I've used call symputx to create a list of macro variables Item 1 to Item N and now I want to transfer them to an array in another datastep so that spot 1 in the array gets Item1, spot 2 gets Item2, etc.
 
do j=1 to &num_OR;
    rulesUsed{j}=&&Item&j;
    end;
I read that the double ampersand syntax is the way to reference macro variables like this but I keep getting all sorts of errors. I'm sure there's a simple way around this but I'm new to SAS and no document I've read through that's come up in searches mentions this exact type of problem.
 
PROC Star
Posts: 1,836

Re: Dynamic macro variable access

Can you please post the log that indicates those errors and your full code, sample data etc

Occasional Contributor
Posts: 9

Re: Dynamic macro variable access

Posted in reply to novinosrin
DATA _Null_;
do I = 1 to &num_or;
set CondensedOverrides4 nobs = num_or;
call symputx("Item" !! left(put(I,8.))
,"Rule", "G");
end;
run;

This is how I used call symputx to make a list of macro variables "Item1" through "Item&num_or"
Occasional Contributor
Posts: 9

Re: Dynamic macro variable access

The first line in this error shows me making an array of size &num_or which is what I'm trying to assign the macro variable list to.

 

 

3580 do j=1 to &num_OR;
3581 rulesUsed{j}=&&Item&j;
WARNING: Apparent symbolic reference J not resolved.
NOTE: Line generated by the macro variable "J".
1 &Item&
-
22
WARNING: Apparent symbolic reference ITEM not resolved.
WARNING: Apparent symbolic reference J not resolved.
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string,
a numeric constant, a datetime constant, a missing value, INPUT, PUT.

3582 end;

PROC Star
Posts: 1,836

Re: Dynamic macro variable access

classic problem of timing of maco execution vs datastep execution

Occasional Contributor
Posts: 9

Re: Dynamic macro variable access

Posted in reply to novinosrin
I know they execute at different times but I am confused why this doesn't work since I have tried assigning &Item1 to spot 1 in the array and it works fine
PROC Star
Posts: 1,836

Re: Dynamic macro variable access

please post the full array code, let me try to adjust that to make it work plz

Occasional Contributor
Posts: 9

Re: Dynamic macro variable access

Posted in reply to novinosrin

data ihopethisworks;
set condensedOverrides4;

array Target1 {&num_OR} T1-T%trim(&num_or);
array Target2 {&num_OR} Tar1-Tar%trim(&num_or);
array Override1 {&num_OR} O1-O%trim(&num_or);
array Override2 {&num_OR} Over1-Over%trim(&num_or);
array revised_score {&num_OR} Rev1-Rev%trim(&num_or);
array num_hits {&num_OR} H1-H%trim(&num_or);

array rulesUsed {&num_OR} $3 Rulez1-Rulez%trim(&num_or);

do j=1 to &num_OR;
rulesUsed{j}=&&Item&j;
end;

do j=1 to &num_OR;
Target1{j}=_35;
end;

do j=1 to &num_OR;
Target2{j}=_36;
end;

do j=1 to &num_OR;
Override1{j}=_37;
end;

do j=1 to &num_OR;
Override2{j}=_38;
end;

do j=1 to &num_OR;
revised_score{j}=_39;
end;

do j=1 to &num_OR;
num_hits{j}=_40;
end;

run;

 

 

Here's the full datastep 

PROC Star
Posts: 1,836

Re: Dynamic macro variable access

Here is a small and simpler demo that simulates your needs. Try to replicate in your code and message us back with your feedback

 

%let item1=a;
%let item2=b;
%let item3=c;
%let item4=d;
%let item5=d;

data w;
array t(5) $;
do j=1 to 5;
call symputx('j', j);
t{j}=resolve('&&Item&j');
end;
run;
Occasional Contributor
Posts: 9

Re: Dynamic macro variable access

Posted in reply to novinosrin
%do j = 1 %to &num_or;
  rulesUsed[&j.] = &&item&j;
%end;

The macro approach seems to work, the way you suggested does result in a dataset but gives the previous name of the variable rather than its actual value, kinda weird I can't figure out why. 

PROC Star
Posts: 1,836

Re: Dynamic macro variable access

@S420L  Hi, First off, Are you working in a production environment on a business deliverable or playing for knowledge like me. The approach we are discussing is all about fun and strictly not even close if you the situation is the former.  In that case , we should be paying to attention to wiser advice from @Tom and making it to really work in prod server.

 

My intent here was to show us(you and me) that it is possible to make it macro resolve during data step execution. That was all.

 

Also, did you exactly replicate my code with the call symputx and resolve as demonstrated?

Occasional Contributor
Posts: 9

Re: Dynamic macro variable access

[ Edited ]
Posted in reply to novinosrin

I'm using SAS enterprise to make a business deliverable, while I don't have direct server access (I'm literally the only person in my department that can program at all, making something for them to give to the systems people) I obviously would like it to work in a production environment so that other programmers don't have to waste their time redoing things.

 

No I didn't add the part with resolve in I will try that now. Will the macro variable approach not work in a server environment?

Super User
Super User
Posts: 8,127

Re: Dynamic macro variable access


@S420L wrote:
DATA _Null_;
do I = 1 to &num_or;
set CondensedOverrides4 nobs = num_or;
call symputx("Item" !! left(put(I,8.))
,"Rule", "G");
end;
run;




This is how I used call symputx to make a list of macro variables "Item1" through "Item&num_or"

Why are you setting all of the macro variables to the same value, Rule ?

 

If you already have the data in the dataset CondensedOverrides4 then just use those values. No need for macro variables.

proc transpose data=CondensedOverrides4 
  prefix=rulesUsed
  out=want (drop=_name_)
;
var rule ;
run;

This code is only converting a max of &NUM_OR observations, even if there are more in the dataset.  Is the macro variable NUM_OR some type of upper bound on the maximum number of rules you can handle? 

 

Or are you just confusing the macro variable NUM_OR with the data step variable NUM_OR which will be set by the NOBS option on the SET statement?

 

Super User
Super User
Posts: 8,127

Re: Dynamic macro variable access


@S420L wrote:
I've used call symputx to create a list of macro variables Item 1 to Item N and now I want to transfer them to an array in another datastep so that spot 1 in the array gets Item1, spot 2 gets Item2, etc.
 
do j=1 to &num_OR;
    rulesUsed{j}=&&Item&j;
    end;
I read that the double ampersand syntax is the way to reference macro variables like this but I keep getting all sorts of errors. I'm sure there's a simple way around this but I'm new to SAS and no document I've read through that's come up in searches mentions this exact type of problem.
 

The value of the data step variable J has nothing to do with the value of the macro variable J. 

 

The macro processor deals with any macro code or macro variable references and passes the resulting strings off to SAS to interpret as SAS code. 

 

So if NUM_OR=4 and  J=1 and ITEM=1 is 234 then you ran this data step.

do j=1 to 4;
    rulesUsed{j}=234;
end;

Which will just make 4 copies of the same value into the array.

 

Ask a Question
Discussion stats
  • 13 replies
  • 122 views
  • 0 likes
  • 3 in conversation