View previous topic :: View next topic
|
Author |
Message |
sushanth bobby
Senior Member
Joined: 29 Jul 2008 Posts: 1020 Location: India
|
|
|
|
Hi,
I am trying to read a dataset using SAS, somehow data is not getting read properly.
Code: |
My SAS job
//SASSTEP EXEC SAS
//IFILE DD DSN=HXSULL.QUERY.TEST,DISP=SHR
//SYSIN DD *
OPTIONS NOCENTER;
DATA FILE;
INFILE IFILE;
INPUT @1 ID 3.0
@5 NAME $CHAR10.
;
PROC PRINT DATA=FILE;
|
Input file
Code: |
127 GERMANY
200 FRANCE
201 ARGENTINA
300 UK
400 SPAIN
501 AUSTRALIA
603 DENMARK
704 SWEDEN
|
SAS LIST
Code: |
The SAS System
Obs ID NAME
1 127 200 FRANCE
2 201 300 UK
3 400 501 AUSTRA
4 603 704 SWEDEN
|
SASLOG
Code: |
1 OPTIONS NOCENTER;
2 DATA FILE;
3 INFILE IFILE;
4 INPUT @1 ID 3.0
5 @5 NAME $CHAR10.
6 ;
NOTE: The infile IFILE is:
Dsname=HXSULL.QUERY.TEST,
Unit=3390,Volume=SMS249,Disp=SHR,Blksize=4096,
Lrecl=4092,Recfm=VB
NOTE: 8 records were read from the infile IFILE.
The minimum record length was 6.
The maximum record length was 13.
NOTE: SAS went to a new line when INPUT statement reached past the end of a line
NOTE: The data set WORK.FILE has 4 observations and 2 variables.
NOTE: The DATA statement used 0.02 CPU seconds and 8692K.
|
I was expecting an output like
Code: |
127 GERMANY
200 FRANCE
201 ARGENTINA
300 UK
400 SPAIN
501 AUSTRALIA
603 DENMARK
704 SWEDEN
|
Thank You in advance,
Sushanth |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
You need to handle the variable length records:
Code: |
OPTIONS NOCENTER;
DATA FILE;
INFILE IFILE LENGTH=RL;
INPUT @1 ID 3.0
@
;
RECLEN = RL ;
NAMELEN = RECLEN - 4 ;
INPUT @5 NAME $VARYING. NAMELEN;
PROC PRINT DATA=FILE; |
|
|
Back to top |
|
|
sushanth bobby
Senior Member
Joined: 29 Jul 2008 Posts: 1020 Location: India
|
|
|
|
Thank You Very Much Robert,
I didn't think, SAS will consider it as a variable length since i specified
starting from position 5, read 10 character.
After your variable length enlightment, i used the special character & in my sas code.
Code: |
OPTIONS NOCENTER;
DATA FILE;
INFILE IFILE;
INPUT @1 ID 3.0
@5 NAME & $CHAR10.
;
PROC PRINT DATA=FILE;
|
to get the following
Code: |
The SAS System
Obs ID NAME
1 127 GERMANY
2 200 FRANCE
3 201 ARGENTINA
4 300 UK
5 400 SPAIN
6 501 AUSTRALIA
7 603 DENMARK
8 704 SWEDEN
|
Can you explain the below from your code.
Code: |
NAMELEN = RECLEN - 4 ;
INPUT @5 NAME $VARYING. NAMELEN;
|
Thank You,
Sushanth |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
The INFILE statement in my code assigns the record length to RL. I assign that value to variable RECLEN, then subtract 4 bytes from it (3 id, 1 space) to come up with the name length. INPUT @5 NAME $VARYING. NAMELEN; tells SAS to read NAME as a variable length character variable starting in position 5 and going for NAMELEN bytes. Note the period for the format is on the $VARYING. not on the NAMELEN.
Your original code produced the results it did because it start reading a 10-byte fixed length variable in position 5. Since it couldn't read all 10 bytes from the current record, SAS went to the next line and read 10 bytes, starting in position 1, for variable NAME. This NOTE tells you that this happened:
Code: |
NOTE: SAS went to a new line when INPUT statement reached past the end of a line |
|
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
I forgot to mention, SAS found the file to be variable length:
Code: |
The minimum record length was 6.
The maximum record length was 13. |
and that's why the use of a 10-byte fixed length data file for NAME didn't work. If any of the data lines was 15 bytes, SAS would not have gone to the next line for that record. |
|
Back to top |
|
|
sushanth bobby
Senior Member
Joined: 29 Jul 2008 Posts: 1020 Location: India
|
|
|
|
Thank You Robert for that explanation. |
|
Back to top |
|
|
Phrzby Phil
Senior Member
Joined: 31 Oct 2006 Posts: 1042 Location: Richmond, Virginia
|
|
|
|
I'm on SAS 9.1.3 and reading from a VB file works fine for me without doing this.
What version are you on? |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
It all depends upon the specific situation -- since he was reading a fixed 10-byte variable starting in byte 5, SAS (all versions) will go to next line if there are not 14 (or more) bytes in the record. I don't believe SAS goes to the next line if you say
Code: |
LENGTH NAME $ 10;
INPUT @5 NAME ; |
but I haven't tested that to make sure.
If your code does not explicitly give a starting position and the length of the variable to read, your code may not exhibit the same behavior -- even for a variable blocked file. |
|
Back to top |
|
|
Phrzby Phil
Senior Member
Joined: 31 Oct 2006 Posts: 1042 Location: Richmond, Virginia
|
|
|
|
Oh, right. I don't have such a file to test with now, but try this INFILE option:
TRUNCOVER
overrides the default behavior of the INPUT statement when an input data record is shorter than the INPUT statement expects. By default, the INPUT statement automatically reads the next input data record. TRUNCOVER enables you to read variable-length records when some records are shorter than the INPUT statement expects. Variables without any values assigned are set to missing. |
|
Back to top |
|
|
sushanth bobby
Senior Member
Joined: 29 Jul 2008 Posts: 1020 Location: India
|
|
|
|
TRUNCOVER works!
Code: |
OPTIONS NOCENTER;
DATA FILE;
INFILE IFILE TRUNCOVER;
INPUT @1 ID 3.0
@5 NAME $CHAR10.
;
PROC PRINT DATA=FILE; |
Thanks for that Phrzby Phil
I am using SAS (r) Proprietary Software Release 8.2 (TS2M0 DBCS2944) |
|
Back to top |
|
|
|