- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
A data step can have one datalines block.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug
"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings
SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation