BookmarkSubscribeRSS Feed
S420L
Calcite | Level 5
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.
 
13 REPLIES 13
novinosrin
Tourmaline | Level 20

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

S420L
Calcite | Level 5
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"
S420L
Calcite | Level 5

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;

novinosrin
Tourmaline | Level 20

classic problem of timing of maco execution vs datastep execution

S420L
Calcite | Level 5
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
novinosrin
Tourmaline | Level 20

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

S420L
Calcite | Level 5

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 

novinosrin
Tourmaline | Level 20

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;
S420L
Calcite | Level 5
%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. 

novinosrin
Tourmaline | Level 20

@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?

S420L
Calcite | Level 5

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?

Tom
Super User Tom
Super User

@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?

 

Tom
Super User Tom
Super User

@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.

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 13 replies
  • 1024 views
  • 0 likes
  • 3 in conversation