DATA Step, Macro, Functions and more

Dynamic Macrovariable and counter

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 143
Accepted Solution

Dynamic Macrovariable and counter

Hi all,

 

Could you please help with the following issue.

 

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
Frequent Contributor
Posts: 143

Re: Dynamic Macrovariable and counter

[ Edited ]
Posted in reply to Astounding

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

 

View solution in original post


All Replies
Super User
Posts: 19,878

Re: Dynamic Macrovariable and counter

Posted in reply to DmytroYermak

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

Frequent Contributor
Posts: 143

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: 19,878

Re: Dynamic Macrovariable and counter

Posted in reply to DmytroYermak

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.

Frequent Contributor
Posts: 143

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: 5,518

Re: Dynamic Macrovariable and counter

Posted in reply to DmytroYermak

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.

Frequent Contributor
Posts: 143

Re: Dynamic Macrovariable and counter

Posted in reply to Astounding
You are right - I have corrected the code. Thank you.
Super User
Posts: 19,878

Re: Dynamic Macrovariable and counter

Posted in reply to DmytroYermak
Have you looked at the REP option in SurveySelect? Why do 10 iterations?
Frequent Contributor
Posts: 143

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: 19,878

Re: Dynamic Macrovariable and counter

Posted in reply to DmytroYermak

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

Posted in reply to DmytroYermak
<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.

 

We, helpful volunteers, had no way of knowing,

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: 5,518

Re: Dynamic Macrovariable and counter

Posted in reply to DmytroYermak

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.

Frequent Contributor
Posts: 143

Re: Dynamic Macrovariable and counter

[ Edited ]
Posted in reply to DmytroYermak

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: 5,518

Re: Dynamic Macrovariable and counter

Posted in reply to DmytroYermak

%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
Frequent Contributor
Posts: 143

Re: Dynamic Macrovariable and counter

[ Edited ]
Posted in reply to Astounding

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.

Need further help from the community? Please ask a new question.

Discussion stats
  • 17 replies
  • 159 views
  • 1 like
  • 4 in conversation