I have the following code for which I get an error that htere are no data lines or infile statement.
options symbolgen mtrace notes source MPRINT;
%macro datm1;
%do i=1% to 2;
data NEW&i;
libname OLD "/folders/myfolders/bootprocess/";
/*Input D*/
/*datafile="/folders/myfolders/bootprocess/FIT&i..smr/";*/
infile ="/folders/myfolders/bootprocess/FIT&i..smr/";
INPUT @ 1 CHECK $CHAR200.@;
/*DATA NAME IS CHECK WHICH IS INDEXED W/'THETA =' THIS MUST BE EXACT*/
S=INDEX(CHECK,'THETA =');
/*DO LOOP TO PICK OUT CORRECT LINE OF CODE LINE W/STRING WILL BE NUMBERED WITH 1 OTHERS=0*/
/*SCAN FUNCTION ALLOWS VARIABLES TO BE OUTPUT FROM THAT POSITION WITH THE DESIRED NAME*/
IF S>0 THEN DO;
THETA_=SUBSTR(CHECK,S+0,110);
KAF=SCAN(THETA_,3,' ');
KAS=SCAN(THETA_,4,' ');
CL=SCAN(THETA_,5,' ');
V3=SCAN(THETA_,6,' ');
D1=SCAN(THETA_,7,' ');
ALAG =SCAN(THETA_,8,' ');
LOGIT= SCAN(THETA_,9,' ');
OUTPUT;
END;
KEEP KAF KAS CL V3 D1 ALAG LOGIT;
*PROC PRINT;
RUN;
%end;
%mend datm1;
%datm1;
run;
The files fit1.smr and fit2.smr are identical and the program was written to capture the theta values. :
THETA: 1)K0 2)KAS 3)CL 4)V3 5)D1 6)LAG2 7)LOGIT
ETA:
ERR:
ABRIKA1.lst 14.307 eval=631 sig=4.1 sub=18 obs=18 CCIL=NNNN NVI2.0 PV2.0
THETA = 4.96 4.96 470 2210 1.11 4.2 0.151
ETASD = 0.278568 0.00316228
ERRSD =
The extra equal sign makes your INFILE statement look like an assignment statement to create a character variable named INFILE.
If you only want to read this exact output with just the specific THETA values used in this analysis then your code can be much simplier. You could even add a little error trapping.
data NEW&i;
if eof then put 'ERROR: Theta values not found';
infile "/folders/myfolders/bootprocess/FIT&i..smr/" end=eof;
input @;
if _infile_=: 'THETA ' then do;
input @'=' kaf kas cl v3 d1 alag logit ;
output;
stop;
end;
run;
In terms of your macro flow you should first move the constant text, like the LIBNAME statement, out of the %DO loop. In fact you probably want to move the LIBNAME statement out of the macro completely. Either define it before you call the macro or just remove it all together since you are not even referencing the libref that it creates.
%macro datm1;
%local i;
%do i=1 %to 2;
data new&i ;
....
run;
%end;
%mend datm1;
If you wanted the macro to read the line with the names of the THETA elements and use those to generate the variable names to use in the output dataset then you will a little more complicated program.
Move your libname statement outside of the data step. Probably best would be completely outside of the macro.
SAS will consider some statements as implying a Run statement for a previous procedure or data step when encountered. Libname is one of them.
A couple of problems with your macro:
1. the infile statement shouldn't be infile= but, rather, just infile "the_path_and_name";
2. * comments shouldn't be used in a macro,
3. your input statement (to get your variables) didn't work as expected
The following worked for me:
%macro datm1; %do i=1% to 2; data NEW&i; libname OLD "/folders/myfolders/bootprocess/"; infile "/folders/myfolders/bootprocess/FIT&i..smr"; INPUT @; S=INDEX(_infile_,'THETA ='); /*DO LOOP TO PICK OUT CORRECT LINE OF CODE LINE W/STRING WILL BE NUMBERED WITH 1 OTHERS=0*/ /*SCAN FUNCTION ALLOWS VARIABLES TO BE OUTPUT FROM THAT POSITION WITH THE DESIRED NAME*/ IF S>0 THEN DO; input @ '=' KAF KAS CL V3 D1 ALAG LOGIT; OUTPUT; END; KEEP KAF KAS CL V3 D1 ALAG LOGIT; /* *PROC PRINT; */ RUN; %end; %mend datm1; %datm1;
Art, CEO, AnalystFinder.com
The extra equal sign makes your INFILE statement look like an assignment statement to create a character variable named INFILE.
If you only want to read this exact output with just the specific THETA values used in this analysis then your code can be much simplier. You could even add a little error trapping.
data NEW&i;
if eof then put 'ERROR: Theta values not found';
infile "/folders/myfolders/bootprocess/FIT&i..smr/" end=eof;
input @;
if _infile_=: 'THETA ' then do;
input @'=' kaf kas cl v3 d1 alag logit ;
output;
stop;
end;
run;
In terms of your macro flow you should first move the constant text, like the LIBNAME statement, out of the %DO loop. In fact you probably want to move the LIBNAME statement out of the macro completely. Either define it before you call the macro or just remove it all together since you are not even referencing the libref that it creates.
%macro datm1;
%local i;
%do i=1 %to 2;
data new&i ;
....
run;
%end;
%mend datm1;
If you wanted the macro to read the line with the names of the THETA elements and use those to generate the variable names to use in the output dataset then you will a little more complicated program.
This solution worked perfectly.
Thanks
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.