Hello forum,
i have problems using loop statements outside of a data step.
I have this data step and want to run it several times (e.g. 8 times) :
data new_data;
set test;
first_result = find(number, &start, "i");
run;
My variable is &start and i want to define a macro with a range from e.g. 1-8.
I tried it like below, but it doesn't work:
%macro test(start=1, end=8)
%local start end;
%let start=&start;
%let end=&end;
%do &start %to &end;
data new_data_&start;
set test;
first_result = find(number, &start, "i");
run;
%let start=&start+1;
%end;
&mend test;
%test(start=1,end=8);
Thanks for your help in advance.
The below macro will generate example DATA step code I posted. Still not sure this is what you want. But for a test project, it makes sense to play around with this sort of macro looping.
data test ;
input number $2. ;
cards ;
00
01
12
;
%macro test(start=1, end=8);
%local i;
%do i=&start %to &end;
data new_data_&i;
set test;
first_result = find(number, "&i", "i");
run;
%end;
%mend test;
options mprint ;
%test(start=1,end=8)
The syntax for macro do loops:
%do var=start %to end;
%do i = &start %to &end;
Please post the log with
options mlogic mprint symbolgen;
73 options mlogic mprint symbolgen;
74
75 %macro test (start=1, end=8);
76 %local start end;
77 %let start=&start;
78 %let end=&end;
79 %do i = &start %to &end;
80 data new_data_&start.;
81 set test;
82 first_result = find(number, &start, "i");
83 run;
84 &let start=&start+1;
85 %end;
86 %mend test;
87 %test(start=1, end=8);
MLOGIC(TEST): Ausführung beginnt.
MLOGIC(TEST): Parameter START besitzt Wert 1
MLOGIC(TEST): Parameter END besitzt Wert 8
MLOGIC(TEST): %LOCAL START END
MLOGIC(TEST): %LET (Variablenname ist START)
SYMBOLGEN: Makrovariable START wird in 1 aufgelöst
MLOGIC(TEST): %LET (Variablenname ist END)
SYMBOLGEN: Makrovariable END wird in 8 aufgelöst
SYMBOLGEN: Makrovariable START wird in 1 aufgelöst
SYMBOLGEN: Makrovariable END wird in 8 aufgelöst
MLOGIC(TEST): %DO Schleife startet; Indexvariable I; Startwert 1; Stoppwert 8; By-Wert 1.
SYMBOLGEN: Makrovariable START wird in 1 aufgelöst
MPRINT(TEST): data new_data_1;
MPRINT(TEST): set test;
SYMBOLGEN: Makrovariable START wird in 1 aufgelöst
MPRINT(TEST): first_result = find(number, 1, "i");
MPRINT(TEST): run;
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
11578:63 1:2
NOTE: Komprimierung für Datei WORK.NEW_DATA_1 deaktiviert, da Komprimierungsoverhead Dateigröße erhöhen würde.
NOTE: There were 100 observations read from the data set WORK.TEST.
NOTE: The data set WORK.NEW_DATA_1 has 100 observations and 3 variables.
NOTE: Verwendet wurde: DATA statement - (Gesamtverarbeitungszeit):
real time 0.01 seconds
cpu time 0.00 seconds
WARNING: Apparent symbolic reference LET not resolved.
180: ZEILE und SPALTE können nicht ermittelt werden.
NOTE: NOSPOOL is on. Rerunning with OPTION SPOOL might allow recovery of the LINE and COLUMN where the error has occurred.
ERROR 180-322: Statement is not valid or it is used out of proper order.
SYMBOLGEN: Makrovariable START wird in 1 aufgelöst
MPRINT(TEST): &let start=1+1;
MLOGIC(TEST): %DO Schleife Indexvariable I ist jetzt 2; Schleife wird wiederholt.
SYMBOLGEN: Makrovariable START wird in 1 aufgelöst
MPRINT(TEST): data new_data_1;
MPRINT(TEST): set test;
SYMBOLGEN: Makrovariable START wird in 1 aufgelöst
MPRINT(TEST): first_result = find(number, 1, "i");
MPRINT(TEST): run;
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
11583:64 1:2
NOTE: Komprimierung für Datei WORK.NEW_DATA_1 deaktiviert, da Komprimierungsoverhead Dateigröße erhöhen würde.
NOTE: There were 100 observations read from the data set WORK.TEST.
NOTE: The data set WORK.NEW_DATA_1 has 100 observations and 3 variables.
NOTE: Verwendet wurde: DATA statement - (Gesamtverarbeitungszeit):
When writing a macro, often it's helpful to start by writing working SAS code with no macro statements. Then after you have that, you can work on writing a macro to generate that code. I know your loop would run 8 times, but if you were going to write two DATA steps without any macro code, what would they look like? Something like:
data new_data_1;
set test;
first_result = find(number, "1", "i");
run;
data new_data_2;
set test;
first_result = find(number, "2", "i");
run;
?
I think the above is syntactically correct, but I doubt it's what you want. It would make sense if your goal is to search a character variable named NUMBER, to see if it has a "1" or a "2" in it.
Before worrying about writing a macro, can you provide a small amount of example data, ideally a DATA step with the CARDS statement to make work.test? And also provide the DATA step code that is working to make the dataset you want. Also describe big picture / goal (what are you doing? why do you want to make 8 datasets?)
If i am going to write two DATA steps without any macro code, it would exactly look like yours. It's exactly what i want. In the test-Data are just numbers and letters. Yet it's just a test project for me.
The below macro will generate example DATA step code I posted. Still not sure this is what you want. But for a test project, it makes sense to play around with this sort of macro looping.
data test ;
input number $2. ;
cards ;
00
01
12
;
%macro test(start=1, end=8);
%local i;
%do i=&start %to &end;
data new_data_&i;
set test;
first_result = find(number, "&i", "i");
run;
%end;
%mend test;
options mprint ;
%test(start=1,end=8)
Your code was exactly what i want and it works well. Thanks a lot. 🙂
Just a note that when you do this:
data new_data_&i;
set test;
Your starting point is always TEST so that your data from the previous iteration does not affect the new iteration. Sometimes that is what you want and sometimes it's not.
%macro test(start=, end=)
%do i = &start %to &end;
data new_data_&i;
set test;
first_result = find(number, "&i", "i");
run;
%end;
%mend test;
%test(start=1,end=8);
@MaxiHösi wrote:
Hello forum,
i have problems using loop statements outside of a data step.
I have this data step and want to run it several times (e.g. 8 times) :
data new_data; set test; first_result = find(number, &start, "i"); run;
My variable is &start and i want to define a macro with a range from e.g. 1-8.
I tried it like below, but it doesn't work:
%macro test(start=1, end=8) %local start end; %let start=&start; %let end=&end; %do &start %to &end; data new_data_&start; set test; first_result = find(number, &start, "i"); run; %let start=&start+1; %end; &mend test; %test(start=1,end=8);
Thanks for your help in advance.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Lock in the best rate now before the price increases on April 1.
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.