Hi everyone,
I would like to read in data with datalines in a data step. The input via datalines should be, however, depending on a macro variable:
%let myVar = XYZ;
data test;
input z;
if "&myVar." eq "XYZ" then do;
datalines;
1
2
3
;
end;
run;
I get an error: "There was 1 unclosed DO block".
If I do the math, I have 1 DO statement and 1 end statement.
Does anyone have an idea? I know that I could do it with a macro but somehow I prefer that setup.
Thank you.
Best!
What is the goal here? This is definitely not the right setup 🙂 Do you want to read all the data only if the macro variable is equal to some value? And what if it is not?
Hi there,
thanks for your fast response. 🙂
I should be more precise in the example. If a variable has a certain value, some data should be read in with datalines, else different data should be read in:
%let myVar = XYZ;
data test;
input z;
if "&myVar." eq "XYZ" then do;
datalines;
1
2
3
;
end;
else do;
datalines;
4
5
6
;
end;
run;
Since SAS 9.4M6 (or M5?), %if-%then %do-%end can be used in open code, and you can conditionally feed your datalines block to the interpreter:
%let myVar = XYZ;
data test;
input z;
%if &myVar. eq XYZ %then %do;
datalines;
1
2
3
;
%end;
%if &myVar. ne XYZ %then %do;;
datalines;
4
5
6
;
%end;
Why you must use macro code here:
the DATALINES statement ends the data step; what follows can only be only data, and the DATALINES statement must always be the last statement of your data step code. So you cannot wrap a data step do/end around it.
Up to the most recent SAS versions, it would not have been possible to do that, as you would have needed a macro definition, and datalines can't be used in a macro; similarly, macro triggers are not resolved in a datalines block. But the addition of %if in open code has made it possible to use conditional datalines blocks.
Just because you think it should work differently, it is NOT a bug. In fact it makes perfect sense, once you're familiar with the workings of a data step. It is of course properly documented.
You can put ANYTHING into a datalines block, including things that usually would be interpreted as data step code or macro code. Therefore the restrictions.
A data step can have one datalines block.
So you want to use different data based on the value of a macro variable?
Since the macro processor is used to dynamically generate code just use it to dynamically generate the code.
But there is no need to change the DATALINES. Either create two datasets.
data xyz;
input z;
datalines;
1
2
3
;
data not_xyz;
input z;
datalines;
4
5
6
;
%let myvar=xyz;
data want;
set &myvar;
run;
Or make one dataset with two different groups of data.
data test_data;
input group $ @;
do until(z=.) ;
input z @;
if z ne . then output;
end;
cards;
XYZ 1 2 3 .
NOT_XYZ 4 5 6 .
;
data want ;
set test_data;
where group = "&myvar";
run;
Hi @AndreasF
Would this solution solve your problem ?
%let myVar = XYZ;
data test;
input z;
if "&myVar." eq "XYZ" then output;
datalines;
1
2
3
;
run;
Hi,
You already have some nice hints for your issue but let me share one more: PARMCARDS
filename XYZ temp;
options PARMCARDS=XYZ;
PARMCARDS4;
1
2
3
;;;;
filename noXYZ temp;
options PARMCARDS=noXYZ;
PARMCARDS4;
4
5
6
;;;;
%let m = ABC;
data test;
if "&m." = "XYZ" then infile XYZ;
else infile noXYZ;
input x;
run;
proc print data = test;
run;
%let m = XYZ;
data test;
if "&m." = "XYZ" then infile XYZ;
else infile noXYZ;
input x;
run;
proc print data = test;
run;
All the best
Bart
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.