DATA Step, Macro, Functions and more

Reading Text

Reply
Frequent Contributor
Posts: 130

Reading Text

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

 

Super User
Posts: 6,626

Re: Reading Text

Posted in reply to jacksonan123

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 =:

 

 

Frequent Contributor
Posts: 130

Re: Reading Text

Posted in reply to Astounding
This is the statement so the number of spaces may be two or three. How
should that be handled?

NO. OF SIG. DIGITS IN FINAL EST.: 2.9

Second, =: will include leading blanks when making the comparison. You
might switch to the INDEX function instead of using =:

Are you referring to the flag_section1=1?


Super User
Posts: 6,626

Re: Reading Text

Posted in reply to jacksonan123

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.

Frequent Contributor
Posts: 130

Re: Reading Text

Posted in reply to Astounding
I tried to play with the scan function by giving it a delimiter etc but it
kept returning 0. It is not finding the 2.9.
Super User
Posts: 6,626

Re: Reading Text

Posted in reply to jacksonan123

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' 

Frequent Contributor
Posts: 130

Re: Reading Text

Posted in reply to Astounding
When I tried your code

if index(_infile_ , 'NO. OF SIG. DIGITS IN FINAL EST.:') and scan(_infile_,
-1,'') = '2.9' then flag_section1 =1, the file was not being read.
Therefore I combined your code with my original code:

input @; if _infile_ =: 'NO. OF SIG. DIGITS IN FINAL EST.: 2.9' then
flag_section1 =1;

When this was done I get the correct answer (see below) when I ran i=6 where
OBS 2 and 6 had the value =2.9.

DISTRIBUTION D DATA


Obs

flag_section1


1

0


2

1


3

0


4

0


5

0


6

1






Super User
Posts: 6,626

Re: Reading Text

Posted in reply to jacksonan123

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.

Frequent Contributor
Posts: 130

Re: Reading Text

Posted in reply to Astounding
There is a space between the ' '. This code 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;


Frequent Contributor
Posts: 130

Re: Reading Text

Posted in reply to jacksonan123

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;

 

 

Super User
Posts: 13,293

Re: Reading Text

Posted in reply to jacksonan123

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

Frequent Contributor
Posts: 130

Re: Reading Text

I tried this code and I also tried to edit it but no luck, it didn't work.
Ask a Question
Discussion stats
  • 11 replies
  • 174 views
  • 1 like
  • 3 in conversation