- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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 =:
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
kept returning 0. It is not finding the 2.9.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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'
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
%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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content