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.
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
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.