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-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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