BookmarkSubscribeRSS Feed
GeorgeSAS
Lapis Lazuli | Level 10

Hello everyone,

I have a raw data with only one row,but it is long.

I can use filename and infile to read it into sas without problem.

filename raw01  "c:\test\raw01.txt" lrecl=1024 ;

the raw01.txt has only one row, and its contents is :"0000001 11CA001CA0CAUSCA0010600031CA57750184NYUS .........."

 

Because the raw data only has one row, I want to imbed its content from external file to the program code itself .so I want to write a code like this:

filename raw01 "  0000001         11CA001CA0CAUSCA0010600031CA57750184NYUSNY  410102F1091 442411  1W609221911012020042003U UND                                1  K743300 095   3090311R092 21J189 61K743                                                                                                                                                            03 J189 K743 R092                                                                                      101  11100                              100 6YNNNNNNNNNNNNNN                                                                                                                                                                                                                                                                                NNNN                        05";
      data rawread;
         infile raw01 ;

         input (id 
                 loc1
                 loc2
                 xxm   
                 trr
                x1-x20
                 y
                m1-m20
                ) ( $ 4-9 $ 21-22 $ 29-30 $ 146-149 @ 163 f2.0 @165 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.  $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
 @ 341 f2.0 @344 20 * $ 5.) ;

    
      run;

The error happen in the filename part. 

 

If this idea is feasible, would you please help me correct my code?

 

Thanks!

9 REPLIES 9
ballardw
Super User

If the text doesn't change then paste into a DATALINES block in the input statement. If the text in that file does change then use the first version that you said works.

 

data rawread;
input (id 
        loc1
        loc2
        xxm   
        trr
       x1-x20
        y
       m1-m20
       ) ( $ 4-9 $ 21-22 $ 29-30 $ 146-149 @ 163 f2.0 @165 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.  $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
 @ 341 f2.0 @344 20 * $ 5.) ;
 datalines;
   0000001         11CA001CA0CAUSCA0010600031CA57750184NYUSNY  410102F1091 442411  1W609221911012020042003U UND                                1  K743300 095   3090311R092 21J189 61K743                                                                                                                                                            03 J189 K743 R092                                                                                      101  11100                              100 6YNNNNNNNNNNNNNN                                                                                                                                                                                                                                                                                NNNN                        05
;
run;

With a datalines (or cards) the data goes on the line(s) following and ends with a ; AFTER the last line of data. If there is no INFILE statement and a datalines is present then the INPUT statement reads from datalines.

 

Note that there are no quotes around the data and that the data lines do not end in semicolons. If you data contains semicolons to be read then use DATALINES4 instead of Datalines and end the data with 4 semicolons such as ;;;;

GeorgeSAS
Lapis Lazuli | Level 10

Thank you ballardw,

 

the dataline works, but if I want to use this in a 'filename' like statement(define the input data outside of datastep,but not use macro variable), is this possible?

ballardw
Super User

@GeorgeSAS wrote:

Thank you ballardw,

 

the dataline works, but if I want to use this in a 'filename' like statement(define the input data outside of datastep,but not use macro variable), is this possible?


That is exactly what

filename raw01  "c:\test\raw01.txt" lrecl=1024 ;

does. There is not macro variable in the filename code.

 

With the above filename then this would read the data, and sounds like what you have done in the past. So I am very confused about exactly what you are actually attempting. 

     data rawread;
         infile raw01 ;

         input (id 
                 loc1
                 loc2
                 xxm   
                 trr
                x1-x20
                 y
                m1-m20
                ) ( $ 4-9 $ 21-22 $ 29-30 $ 146-149 @ 163 f2.0 @165 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.  $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
 @ 341 f2.0 @344 20 * $ 5.) ;

    
      run;

There are limits as to what and how a data step will read data. You could add a small amount of text around your data and use an %include file and the code would look like:

 

data one;
   input <input statemen>
   ;
%include "path\filename.txt";
run;

But that will not actually gain anything over the Filename and potentially lead to confusion as most people use %include files to hold repeated code not text.

 

 

Can you describe what this attempt is supposed to improve if it works?

If you want the entire line to appear in the log for instance you could add a put _infile_; in the step that parsed the data line.

 

You also would have an interesting time attempting to read a macro variable from a datalines block. I'll let you experiment to see if you can determine why.

GeorgeSAS
Lapis Lazuli | Level 10

Thank you ballardw,

 

The datalines; statement inside a sas data step for my case works. I want move the body of the datalines streams from inside a data step to outside of the data step. 

I want to try it in a macro:

%let sc =    0000001         11CA001CA0CAUSCA0010600031CA57750184NYUSNY  410102F1091 442411  1W609221911012020042003U UND                                1  K743300 095   3090311R092 21J189 61K743                                                                                                                                                            03 J189 K743 R092                                                                                      101  11100                              100 6YNNNNNNNNNNNNNN                                                                                                                                                                                                                                                                                NNNN                        05;
data rawread;
input (id 
        loc1
        loc2
        xxm   
        trr
       x1-x20
        y
       m1-m20
       ) ( $ 4-9 $ 21-22 $ 29-30 $ 146-149 @ 163 f2.0 @165 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.  $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
 @ 341 f2.0 @344 20 * $ 5.) ;
 datalines;
 &sc.
;
run;

I want to use a macro &sc. to replace the datalines data stream, but my code not work.

 

Please advise.

 

Thanks!

mkeintz
PROC Star

You apparently want inline data, but you want it in a filename reference rather than following a datalines statement.  You might get this using the PIPE filename type.

 

If you use windows, then the argument of the pipe can be an ECHO statement:

 

filename txt pipe 'echo 1 2 3 4'  lrecl=2048;
data want;
  infile txt;
  input x y z a;
run;
--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
GeorgeSAS
Lapis Lazuli | Level 10

Thank you mkeintz!

 

The code works on PC:

*filename txt_pc pipe 'echo 0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05' lrecl=2048;
filename txt_pc pipe 'echo    0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05' lrecl=2048;

data want; infile txt_pc; input id $ 4-9 loc1 $ 21-22 loc2 $ 29-30 xxm $ 146-149 trr 163-164 @165 (x1-x20) ($7.) y 341-342 @344 (m1-m20) ($5.) ; run;

But it not work on unix. How to fix the code on unix?

Tom
Super User Tom
Super User

You need to explain WHY you want to do this to get a better solution to your actual problem.

 

But in the meantime let's look at the difficulties of trying to do what you want.

First it is extremely hard to embed a line of data into a program and not have it get mangled by the editor (either the program or the human editor).  Especially if you want to embed a line that is over 400 characters long.

Second it is even harder to do that with a %LET statement.

 

It is easier to enter the text as a string in a program.  That will help a little since it is not as easy for the SAS parse to mess up the string if it is properly quotes.  Although it would still be easy for editor(s) to mess up the content, especially with such a really long line with so many spaces.

So something like this.

filename mydata temp;
data _null_;
  file mydata ;
  put '   0000001         11CA001CA0CAUSCA0010600031CA57750184NYUSNY  410102F1091 442411  1W609221911012020042003U UND                                1  K743300 095   3090311R092 21J189 61K743                                                                                                                                                            03 J189 K743 R092                                                                                      101  11100                              100 6YNNNNNNNNNNNNNN                                                                                                                                                                                                                                                                                NNNN                        05';
run;

If you did already have the value in a macro variable then you could replace the string literal in the PUT statement with a reference to the macro variable.

put "&sc";

Then your program just needs to read from the temp file your data _null_ step created.  

You should simplify your INPUT statement to make it more readable (and hence more maintainable).

data rawread;
infile mydata;
input 
  id   $ 4-9
  loc1 $ 21-22
  loc2 $ 29-30
  xxm  $ 146-149 
  trr    163-164
 @165 (x1-x20) ($7.)
  y      341-342
 @344 (m1-m20) ($5.)
;
run;

It it even easier if the data is already in a dataset.  But in that case just keep it in the dataset and don't convert it to either text or macro variable.  Let's say you have the data in a variable called LINE in a dataset called RAWDATA.  Then you can use the following _INFILE_ "trick" to use the INPUT statement to read from the line of data.

filename dummy temp;
data _null_;
  file dummy;
  put 'This will be ignored';
run;
data rawread;
  set rawdata ;
  infile dummy lrecl=2000 truncover ;
  input @ ;
  _infile_ = line ;
  input 
    id   $ 4-9
    loc1 $ 21-22
    loc2 $ 29-30
    xxm  $ 146-149 
    trr    163-164
   @165 (x1-x20) ($7.)
    y      341-342
   @344 (m1-m20) ($5.)
   @1  @@
  ;
run;

 

 

GeorgeSAS
Lapis Lazuli | Level 10

Thank you Tom!

 

filename mydata temp2;
data _null_;
  file mydata ;
  put '   0000001         11CA001CA0CAUSCA0010600031CA57750184NYUSNY  410102F1091 442411  1W609221911012020042003U UND                                1  K743300 095   3090311R092 21J189 61K743                                                                                                                                                            03 J189 K743 R092                                                                                      101  11100                              100 6YNNNNNNNNNNNNNN                                                                                                                                                                                                                                                                                NNNN                        05';
run;

 

For the code above, when use "filename mydata temp;" the in-steam data will reduce one digit from the left, to use this code generate correct result, I modified your code and it works well, here is code(I added one extra space in the left):

 

filename mydata temp;
data _null_;
  file mydata ;
  put '    0000001         11CA001CA0CAUSCA0010600031CA57750184NYUSNY  410102F1091 442411  1W609221911012020042003U UND                                1  K743300 095   3090311R092 21J189 61K743                                                                                                                                                            03 J189 K743 R092                                                                                      101  11100                              100 6YNNNNNNNNNNNNNN                                                                                                                                                                                                                                                                                NNNN                        05';
run;

 Thank you!

GeorgeSAS
Lapis Lazuli | Level 10

----To summarize all the great solutions,

 

/*1 filename extrnal file*/
filename raw01 "c:\test\raw01.txt" lrecl=1024 ;
filename raw01 " 0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05";
data rawread;
infile raw01 ;

input (id
loc1
loc2
xxm
trr
x1-x20
y
m1-m20
) ( $ 4-9 $ 21-22 $ 29-30 $ 146-149 @ 163 f2.0 @165 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
$ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
@ 341 f2.0 @344 20 * $ 5.) ;


run;
/*2 in stream*/
data rawread;
input (id
loc1
loc2
xxm
trr
x1-x20
y
m1-m20
) ( $ 4-9 $ 21-22 $ 29-30 $ 146-149 @ 163 f2.0 @165 $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
$ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7. $ 7.
@ 341 f2.0 @344 20 * $ 5.) ;
datalines;
0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05
;
run;
/*3 filename tempfilename mydata temp;*/
data _null_;
file mydata ;
*put ' 0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05';
put ' 0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05';
run;
filename mydata temp3;
data _null_;
file mydata ;
*put ' 0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05';
put ' 0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05';
run;*/

data rawread003;
infile mydata;
input
id $ 4-9
loc1 $ 21-22
loc2 $ 29-30
xxm $ 146-149
trr 163-164
@165 (x1-x20) ($7.)
y 341-342
@344 (m1-m20) ($5.)
;
run;
/*4. pipe on pc*/
filename txt_pc pipe 'echo 0000001 11CA001CA0CAUSCA0010600031CA57750184NYUSNY 410102F1091 442411 1W609221911012020042003U UND 1 K743300 095 3090311R092 21J189 61K743 03 J189 K743 R092 101 11100 100 6YNNNNNNNNNNNNNN NNNN 05' lrecl=2048;
data want;
infile txt_pc;
input
id $ 4-9
loc1 $ 21-22
loc2 $ 29-30
xxm $ 146-149
trr 163-164
@165 (x1-x20) ($7.)
y 341-342
@344 (m1-m20) ($5.)
;
run;

 

.....to be updated...

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 9 replies
  • 978 views
  • 0 likes
  • 4 in conversation