I have the following code used to find a line of text in a file:
%macro datm4;
%do i=1 %to 2;
data result&I ;
/*inialization of flag to 0 which will be used to find line of interest*/
retain flag_section1 0 ;
infile "/folders/myfolders/DLBOOTDAT_RIT/data/TEST&i..nm7/TEST&i..lst" END=EOF;
input @; if _infile_ =: 'NO. OF SIG. DIGITS IN FINAL EST.: 2.9' then flag_section1 =1;
if eof then output;
run;
%END;
TITLE ' DISTRIBUTION D DATA';
data FLAG;
set %do i=1 %to 2;RESULT&i %end ;;
run;
%mend datm4;
%datm4;
PROC PRINT DATA =RESULT1;
RUN;
PROC PRINT DATA =RESULT2;
RUN;
The *,lst file that I am searching has a line of text as follows:
NO. OF SIG. DIGITS IN FINAL EST.: 2.9
which I want to capture whenever the value is 2.9 at which time I want the flag_section1 =1. However I am getting a value of zero irrespective of the value (.e. g., when the value is 2,7 or any other non 2.9 value). Some of the prior lines in the file are listed below.
MINIMIZATION TERMINATED
DUE TO ROUNDING ERRORS (ERROR=134)
NO. OF FUNCTION EVALUATIONS USED: 326
NO. OF SIG. DIGITS IN FINAL EST.: 2.9
Can someone tell me why the flag_section is not seeing the number or suggest other code that may be more effective?
Thanks
There may be more, but I see two issues right off the bat.
First, what text are you searching for? More specifically, how many spaces are there between the colon and the 2.9? The actual message vs. your programming statement appear to be different in that regard.
Second, =: will include leading blanks when making the comparison. You might switch to the INDEX function instead of using =:
For both of my comments, I'm focusing on this statement:
if _infile_ =: 'NO. OF SIG. DIGITS IN FINAL EST.: 2.9' then flag_section1 =1;
Given that there could be leading blanks within _INFILE_, and there could be a varying number of spaces following the colon, this might work to handle both issues:
if index(_infile_ , 'NO. OF SIG. DIGITS IN FINAL EST.:') and scan(_infile_, -1) = '2.9' then flag_section1 =1;
Sorry I didn't come up with this earlier.
Sorry, my fault here. SCAN also uses a decimal point as one of its default delimiters. For that part of the test, specify a blank as the only delimiter:
and scan(_infile_, -1, ' ') = '2.9'
Why do you say that you tried my code? I'm not using "=:". I'm using INDEX instead. In the third parameter of SCAN, you removed the blank between the quotes. Put it back in and test again. Better yet, copy/paste the code that I posted.
If your code is now working, it is only because you are using cases where there is only one space between the ":" and the "2.9". It won't work for a different number of spaces in between.
The code listed below works:
%macro datm4;
%do i=1 %to 210;
data result&I ;
/*inialization of flag to 0 which will be used to find line of interest*/
retain flag_section1 0 ;
infile "/folders/myfolders/DLBOOTDAT_RIT/data/TEST&i..nm7/TEST&i..lst" END=EOF;
if index(_infile_ , 'NO. OF SIG. DIGITS IN FINAL EST.:') and scan(_infile_, -1,'') = '2.9' then flag_section1 =1;
input @; if _infile_ =: 'NO. OF SIG. DIGITS IN FINAL EST.: 2.9' then flag_section1 =1;
if eof then output;
run;
%END;
TITLE ' DISTRIBUTION D DATA';
data FLAG;
set %do i=1 %to 210;RESULT&i %end ;;
run;
%mend datm4;
%datm4;
Perhaps a different input:
input @'NO. OF SIG. DIGITS IN FINAL EST.:' digits; if digits=2.9 then flag_section1=1;
which should read the value following the text using list input and ignores differing numbers of spaces.
And if you actually have a number of flags to set based on different values of 2.9 or such then this is possibly a much more flexible solution
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.