## Dynamic Macrovariable and counter

Solved
Regular Contributor
Posts: 210

# Dynamic Macrovariable and counter

Hi all,

I need to use the following cycle construction:

%do i=1 %to 10;

...

% put seed&i=&&seed&i;

%end;

Definitely it is not correct now. I need to use current number of "i" in the construction "&i".

In my Symbol Table I have some values of seed1, seed2, ..., seed10. Please advise how to amend the code. Thank you!

Accepted Solutions
Solution
‎08-30-2017 02:31 AM
Regular Contributor
Posts: 210

## Re: Dynamic Macrovariable and counter

[ Edited ]

Thank you! It resolves the issue.

Just one question. Is 'i' local or global macrovariable?

Here below is the full code

``````libname mylib 'C:\MYLIB_KP3';

data _null_;
infile datalines dlm=',';
input seedX @@;
n+1;
call symput('seed'!!strip(put(n,2.)),strip(seedX));
datalines;
12345,23456,34567,45678,56789,67891,78912,89123,91234,92345
;
run;

%macro team;

%do i=1 %to 10;

proc surveyselect data = mylib.titanic
method = srs
n = 100
out = sample&i
noprint
seed=&&seed&i;
run;

%end;

%mend team;

%team;``````

and the log:

``````1361  libname mylib 'C:\MYLIB_KP3';
NOTE: Libref MYLIB was successfully assigned as follows:
Engine:        V9
Physical Name: C:\MYLIB_KP3
1362
1363  data _null_;
1364      infile datalines dlm=',';
1365      input seedX @@;
1366          n+1;
1367          call symput('seed'!!strip(put(n,2.)),strip(seedX));
1368          datalines;

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
1367:52
NOTE: SAS went to a new line when INPUT statement reached past the end of a line.
NOTE: DATA statement used (Total process time):
real time           0.00 seconds
cpu time            0.01 seconds

1370  ;
1371  run;
1372
1373  %macro team;
1374
1375      %do i=1 %to 10;
1376
1377          proc surveyselect data = mylib.titanic
1378              method = srs
1379              n = 100
1380              out = sample&i
1381              noprint
1382              seed=&&seed&i;
1383          run;
1384
1385      %end;
1386
1387  %mend team;
1388
1389  %team;
MLOGIC(TEAM):  Beginning execution.
MLOGIC(TEAM):  %DO loop beginning; index variable I; start value is 1; stop value is 10; by value is 1.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample1 noprint seed=12345;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE1 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 2; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample2 noprint seed=23456;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE2 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 3; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample3 noprint seed=34567;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE3 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 4; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample4 noprint seed=45678;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE4 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 5; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample5 noprint seed=56789;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE5 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 6; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample6 noprint seed=67891;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE6 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 7; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample7 noprint seed=78912;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE7 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 8; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample8 noprint seed=89123;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE8 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.01 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 9; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample9 noprint seed=91234;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE9 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.01 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 10; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample10 noprint seed=92345;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE10 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.01 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 11; loop will not iterate again.
MLOGIC(TEAM):  Ending execution.
1390

``````

All Replies
Super User
Posts: 23,320

## Re: Dynamic Macrovariable and counter

Works fine for me, are you sure your macro variables are created and have the correct scope, ie global vs local if required?

``````proc sql noprint;
select name into :name1-
from sashelp.class;
quit;

%macro demo;

%do i=1 %to 10;
%put name&i=&&name&i;
%end;

%mend;

%demo;``````

Output:

40 proc sql noprint;
41 select name into :name1-
42 from sashelp.class;
43 quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds

44
45 %macro demo;
46
47 %do i=1 %to 10;
48 %put name&i=&&name&i;
49 %end;
50
51 %mend;
52
53 %demo;
name1=Alfred
name2=Alice
name3=Barbara
name4=Carol
name5=Henry
name6=James
name7=Jane
name8=Janet
name9=Jeffrey
name10=John

Regular Contributor
Posts: 210

## Re: Dynamic Macrovariable and counter

Thank you, Reeza! Do you mean that i is a macrovariable in a local table? I mean the the construction "%do i=1 %to 10"?

Super User
Posts: 23,320

## Re: Dynamic Macrovariable and counter

I meant your seed macro variables, ie seed1 to seed10.

My 'guess' is that if they're not resolving it's a scope issue. But there could be other reasons. At any rate the code you posted is fine your error is somewhere else.

Regular Contributor
Posts: 210

## Re: Dynamic Macrovariable and counter

[ Edited ]

I actully would like to receive a 10 random samples using the following code:

``````***assigning values of macrovariables seed1-seed10;data _null_;
infile datalines dlm=',';
input seedX @@;
n+1;
call symput('seed'!!strip(put(n,\$2.)),strip(seedX));
datalines;
12345,23456,34567,45678,56789,67891,78912,89123,91234,92345
;
run;

options mprint;
***macros for randomization from set mylib.team;
%macro team;

proc surveyselect data = mylib.team
method = srs
n = 100
out = sample&i
/*noprint*/
seed=&&seed&i;
run;

%mend team;
***generation of 10 random samples, 100 persons each;
%do i=1 %to 10;
%team;
%end;``````

Could you please have a look where is an error.

Super User
Posts: 6,637

## Re: Dynamic Macrovariable and counter

Doesn't your initial DATA step give you an error message?

Incorrect:    \$2.

Correct:   2.

You can't express a numeric value in a character format.

Regular Contributor
Posts: 210

## Re: Dynamic Macrovariable and counter

You are right - I have corrected the code. Thank you.
Super User
Posts: 23,320

## Re: Dynamic Macrovariable and counter

Have you looked at the REP option in SurveySelect? Why do 10 iterations?
Regular Contributor
Posts: 210

## Re: Dynamic Macrovariable and counter

I have to use 10 different "seed"s option in proc surveyselect and output them in different datasets. Is there another way to generate them?
Super User
Posts: 23,320

## Re: Dynamic Macrovariable and counter

DmytroYermak wrote:
I have to use 10 different "seed"s option in proc surveyselect and output them in different datasets. Is there another way to generate them?

That's not really going to give you different results than using the REP option, you can replicate it with the initial seed.

Regular Contributor
Posts: 227

## Re: Dynamic Macrovariable and counter

``````<span class="token macrobound">%macro</span> team(seed)<span class="token punctuation">;</span>

<span class="token procnames">proc</span> <span class="token procnames">surveyselect</span> <span class="token procnames">data</span> <span class="token operator">=</span> mylib<span class="token punctuation">.</span>team
method <span class="token operator">=</span> srs
<span class="token function">n</span> <span class="token operator">=</span> <span class="token number">100</span>
out <span class="token operator">=</span> sample<span class="token operator">&</span>i
<span class="token comment">/*noprint*/</span>
seed<span class="token operator">=&seed</span><span class="token punctuation">;</span>
<span class="token procnames">run</span><span class="token punctuation">;</span>

<span class="token macrobound">%mend</span> team<span class="token punctuation">;</span>
<span class="token comment">***generation of 10 random samples, 100 persons each;<br /></span>%macro do_loop(dimension);
<span class="token macrostatement">%do</span> i<span class="token operator">=</span><span class="token number">1</span> <span class="token macrostatement">%to</span> <span class="token number">&dimension</span><span class="token punctuation">;<br /></span>    %put echo seed&i:&&seed&i;
<span class="token macroname">%team(&&seed&i)</span><span class="token punctuation">;</span>
<span class="token macrostatement">%end</span><span class="token punctuation">;<br />%mend do_loop;<br />%put _user_;<br />%do_loop(1);*testing;<br />%do_loop(10);*ok, then, run whole loop!;<br /><br /></span>``````

your two macro can be made easier to read if you have a parameter for macro team for the seed

this makes the macro named team, unique and unit-testable ,

rather than tied to the macro array in the global symbol table.

this makes the macro with the loop easy to test and then ramp up to call the team macro.

from the phrasing of your original question,

where the error was:

1. in the code which generated the macro array

2. in the loop, which you thought was apparent to you

3. in the surveyselect macro

These ideas of separating the procedure from the loop for testing and development

were laid out by me and Art Carpenter in

http://www.sascommunity.org/wiki/List_Processing_Basics_Creating_and_Using_Lists_of_Macro_Variables

Ron Fehd  macro array maven

Super User
Posts: 6,637

## Re: Dynamic Macrovariable and counter

The answer might very well lie in the code that you haven't shown, the "..." part:

%do i = 1 %to 10;

...

That code could be changing the value of &i.  Here is a sneaky way that could happen.  If "..." includes a call to a macro (%abc), that macro might utilize a variable named &i.  If %abc fails to define &i as %local, then %abc will be using the &i in your loop (%do i=1 %to 10) instead of a new, %local version of &i.

Regular Contributor
Posts: 210

## Re: Dynamic Macrovariable and counter

[ Edited ]

When I run my code I receive the following error:

``````1098 %do i=1 %to 10;
ERROR: The %DO statement is not valid in open code.
1099 %team;

MLOGIC(TEAM): Beginning execution.
WARNING: Apparent symbolic reference I not resolved.
NOTE 137-205: Line generated by the invoked macro "TEAM".
1 proc surveyselect data = mylib.team method = srs n = 100 out = sample&i seed=&&seed&i; run;
-
22
ERROR 22-322: Syntax error, expecting one of the following: ;, (, CERTAIN, CERTSIZE, CERTUNITS, DATA, GROUPS, JTPROBS, M, MAXSIZE, METHOD, MINSIZE, N, NMAX, NMIN, NOPRINT, OUT, OUTALL, OUTHITS, OUTSEED, OUTSIZE, OUTSORT, RANUNI,
RATE, REPS, SAMPRATE, SAMPSIZE, SEED, SELECTALL, SORT, SRSALG, STATS, STRATUMSEED.

WARNING: Apparent symbolic reference I not resolved.
WARNING: Apparent symbolic reference I not resolved.

NOTE: Line generated by the invoked macro "team".``````

Why is my structure '%do ... %to' not functioning?

Super User
Posts: 6,637

## Re: Dynamic Macrovariable and counter

%DO is only permitted inside a macro definition.  If  you want to use it, you will need to define a macro holding your code, and run the macro.

Solution
‎08-30-2017 02:31 AM
Regular Contributor
Posts: 210

## Re: Dynamic Macrovariable and counter

[ Edited ]

Thank you! It resolves the issue.

Just one question. Is 'i' local or global macrovariable?

Here below is the full code

``````libname mylib 'C:\MYLIB_KP3';

data _null_;
infile datalines dlm=',';
input seedX @@;
n+1;
call symput('seed'!!strip(put(n,2.)),strip(seedX));
datalines;
12345,23456,34567,45678,56789,67891,78912,89123,91234,92345
;
run;

%macro team;

%do i=1 %to 10;

proc surveyselect data = mylib.titanic
method = srs
n = 100
out = sample&i
noprint
seed=&&seed&i;
run;

%end;

%mend team;

%team;``````

and the log:

``````1361  libname mylib 'C:\MYLIB_KP3';
NOTE: Libref MYLIB was successfully assigned as follows:
Engine:        V9
Physical Name: C:\MYLIB_KP3
1362
1363  data _null_;
1364      infile datalines dlm=',';
1365      input seedX @@;
1366          n+1;
1367          call symput('seed'!!strip(put(n,2.)),strip(seedX));
1368          datalines;

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
1367:52
NOTE: SAS went to a new line when INPUT statement reached past the end of a line.
NOTE: DATA statement used (Total process time):
real time           0.00 seconds
cpu time            0.01 seconds

1370  ;
1371  run;
1372
1373  %macro team;
1374
1375      %do i=1 %to 10;
1376
1377          proc surveyselect data = mylib.titanic
1378              method = srs
1379              n = 100
1380              out = sample&i
1381              noprint
1382              seed=&&seed&i;
1383          run;
1384
1385      %end;
1386
1387  %mend team;
1388
1389  %team;
MLOGIC(TEAM):  Beginning execution.
MLOGIC(TEAM):  %DO loop beginning; index variable I; start value is 1; stop value is 10; by value is 1.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample1 noprint seed=12345;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE1 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 2; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample2 noprint seed=23456;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE2 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 3; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample3 noprint seed=34567;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE3 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 4; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample4 noprint seed=45678;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE4 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 5; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample5 noprint seed=56789;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE5 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 6; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample6 noprint seed=67891;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE6 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 7; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample7 noprint seed=78912;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE7 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.00 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 8; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample8 noprint seed=89123;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE8 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.01 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 9; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample9 noprint seed=91234;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE9 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.01 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 10; loop will iterate again.
MPRINT(TEAM):   proc surveyselect data = mylib.titanic method = srs n = 100 out = sample10 noprint seed=92345;
MPRINT(TEAM):   run;

NOTE: The data set WORK.SAMPLE10 has 100 observations and 6 variables.
NOTE: PROCEDURE SURVEYSELECT used (Total process time):
real time           0.00 seconds
cpu time            0.01 seconds

MLOGIC(TEAM):  %DO loop index variable I is now 11; loop will not iterate again.
MLOGIC(TEAM):  Ending execution.
1390

``````

☑ This topic is solved.