BookmarkSubscribeRSS Feed
jacksonan123
Lapis Lazuli | Level 10

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

 

11 REPLIES 11
Astounding
PROC Star

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

 

 

jacksonan123
Lapis Lazuli | Level 10
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?


Astounding
PROC Star

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.

jacksonan123
Lapis Lazuli | Level 10
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.
Astounding
PROC Star

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' 

jacksonan123
Lapis Lazuli | Level 10
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






Astounding
PROC Star

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.

jacksonan123
Lapis Lazuli | Level 10
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;


jacksonan123
Lapis Lazuli | Level 10

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;

 

 

ballardw
Super User

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

jacksonan123
Lapis Lazuli | Level 10
I tried this code and I also tried to edit it but no luck, it didn't work.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 11 replies
  • 1582 views
  • 1 like
  • 3 in conversation