- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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)
Next up: SAS Trivia Quiz hosted by SAS on Wednesday May 21.
Register now at https://www.basug.org/events.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
The syntax for macro do loops:
%do var=start %to end;
%do i = &start %to &end;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Please post the log with
options mlogic mprint symbolgen;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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):
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You now have a working loop.
Then it looks like you have data type problem, is your variable "number" character or numeric?
You can also skip the "i" modifier since you are only looking for numbers.
Also, you need to replace the &start in the function call with &i.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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?)
Next up: SAS Trivia Quiz hosted by SAS on Wednesday May 21.
Register now at https://www.basug.org/events.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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)
Next up: SAS Trivia Quiz hosted by SAS on Wednesday May 21.
Register now at https://www.basug.org/events.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Your code was exactly what i want and it works well. Thanks a lot. 🙂
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Parameters within a macro by definition are local, so defining them as local and re-assigning is redundant
- For the FIND function, put the second parameter in quotes as FIND requieres character/string parameters
- DO loop needs to be fixed as others have suggested.
%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.