Hi All,
Is there a more convenient/elegant/efficient way to use the facilities of the INPUT statement to parse a string than this :
data have;
length line $100;
infile datalines truncover;
input line $char.;
datalines;
temperature 25.3
humidity pct 45
dew point 18.2
;
data want(keep=parameter value);
length parameter $32;
input @@;
do until (eof);
set have end=eof;
_infile_ = line;
input @1 parameter & value @@;
output;
end;
datalines;
DUMMY
;
Thanks
PG
Then I think your example is as good as it gets. You might add a STOP statement at the end, but that's really a side issue.
There are some advanced (and dangerous!) techniques that let you place text directly into the PDV by position. Do you want to go that route? Paul Dorfman has written on the topic.
convenient/elegant/efficient I don't know about that.
data need;
set have;
*CALL SCAN(<string>, count, position, length <, <charlist> <, <modifier(s)>>>);
call scan(line,-1,position,length,' ');
parameter = left(substr(line,1,position-1));
value = input(substr(line,position),f8.);
run;
Thanks data_null_, but I am really looking for a way to using the INPUT statement on strings, not for another way to parse this example data.Many programming languages provide for a way to read from strings instead of files and I wonder if there is a less cumbersome way to do it in SAS. - PG
If you are asking can we bypass the INFILE part I think the answer is NO.
The second DATA step seems to imply that there is more than one space between the parameter and the value. If so, why can't you just code:
data want;
length parameter $ 32;
input parameter & value;
datalines;
...
;
As I said above, I'm not trying to solve this particular parsing problem. I am really looking for a way to using the INPUT statement on strings. Many programming languages provide for a way to read from strings instead of files and I wonder if there is a less cumbersome way to do it in SAS. - PG
Then I think your example is as good as it gets. You might add a STOP statement at the end, but that's really a side issue.
There are some advanced (and dangerous!) techniques that let you place text directly into the PDV by position. Do you want to go that route? Paul Dorfman has written on the topic.
PG: Not sure what you are looking for, but the input function can be fairly powerful especially when combined with other functions. How about:
data have;
length line $100;
infile datalines truncover;
input line $char.;
datalines;
temperature 25.3
humidity pct 45
dew point 18.2
;
data want(keep=parameter value);
set have;
line=strip(line);
parameter=input( substr(line,1,index(line," ")-1),$32.);
value=input(substr(line,index(line," ")), 32.);
run;
It is not exactly clear to me what you mean with "to read from strings instead of files".
If you mean that you would like to parse strings in general, then probably your best choice is to use the PERL functions and call routines, not the INPUT statement.
Alternatively you could use probably the SCAN- or the FIND-functions to get yourself the elements of a particular input line.
This too should work:
data have;
length line $100;
infile datalines truncover;
input line $char.;
datalines;
temperature 25.3
humidity pct 45
dew point 18.2
;
data want (keep=parameter value);
set have;
linelen=length(line);
do k=1 to linelen until(((asc<58)*(asc>45)));*<---ASCII codes for numeric characters plus decimal point;
chr=substr(line,k,1);
asc=rank(chr);
end;
parameter=substr(line,1,(k-1));
value=input(substr(line,k,(linelen-k+1)),best.);
run;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.