BookmarkSubscribeRSS Feed
gleebglorb
Calcite | Level 5
data empraw; 
infile empdat firstobs=2 dlm='09'x ;
input name : $6.  lastname : $6. @ ;
input score $ @@ ;
run;

I am having trouble with line hold specifiers.  

My input data looks like this (ignore the formatting issues like spacing)

 

FirstName LastName Score 

Sally    Mae      30       40       50    60 

John    Goe      30       40       50    60 

Matt     Miller      30       40       50    60 

Henry   Mae      30       40       50    60 

 

where score should be read in several times and First and Last name should be retained to output something like this 

 

Sally       Mae      30 

Sally       Mae      40

Sally       Mae      50

Sally       Mae      60

 

I'm currently trying this: 

data empraw; 

infile empdat firstobs=2 dlm='09'x ;

input name : $6.  lastname : $6. @ ;

input score $ @@ ;

run;

 

Right now, it doesn't hold the input buffer, and outputs like this:

 

Sally       Mae      30 

40           50        60

 

What am I doing wrong?

8 REPLIES 8
PeterClemmensen
Tourmaline | Level 20

Where is your input data stored?

gleebglorb
Calcite | Level 5

It's on my computer as a txt file.  The actual line is 

infile 'S:\rawdat\employee\employee.txt'

PeterClemmensen
Tourmaline | Level 20

I suppose this can be done with the input statement. Though, this seems more logical to me

 

data have(drop = score1 - score4);
input FirstName $ LastName $ score1-score4;
array s score1-score4;
do over s;
   score = s;
   output;
end;
datalines;
Sally Mae    30 40 50 60 
John  Goe    30 40 50 60 
Matt  Miller 30 40 50 60 
Henry Mae    30 40 50 60 
;

 

Result:

 

FirstName LastName score 
Sally     Mae      30 
Sally     Mae      40 
Sally     Mae      50 
Sally     Mae      60 
John      Goe      30 
John      Goe      40 
John      Goe      50 
John      Goe      60 
Matt      Miller   30 
Matt      Miller   40 
Matt      Miller   50 
Matt      Miller   60 
Henry     Mae      30 
Henry     Mae      40 
Henry     Mae      50 
Henry     Mae      60 
gleebglorb
Calcite | Level 5

Is there a way to do this using line hold specifiers like @ or @@? The actual data set is much much bigger than what I posted and is still being updated so I don't want to do it with datalines.  

ballardw
Super User

@gleebglorb wrote:

Is there a way to do this using line hold specifiers like @ or @@? The actual data set is much much bigger than what I posted and is still being updated so I don't want to do it with datalines.  


Datalines are just an example. You would use an infile statement to point to the data file.

 

If you always have 4 values to read perhaps:

 

data have;
input FirstName $ LastName $ @;
do i=1 to 4;
   input score  @;
   output;
end;
input;
drop i;
datalines;
Sally Mae    30 40 50 60 
John  Goe    30 40 50 60 
Matt  Miller 30 40 50 60 
Henry Mae    30 40 50 60 
;

If you have missing values on your infile statement you would use one of the options TRUNCOVER or MISSOVER.

 

 

 

gleebglorb
Calcite | Level 5
Would missover/truncover prevent missing observations from being read in? There are a few observations with less than four scores
ballardw
Super User

@gleebglorb wrote:
Would missover/truncover prevent missing observations from being read in? There are a few observations with less than four scores

Missover and truncover are both somewhat different approaches to tell SAS what to do when the expected data runs out before the input instruction is completed. The default for SAS is to attempt to finish reading from the next line, which would be reading non-score values into score and cause invalid data, character not fitting into numeric variables.

 

Use TRUNCOVER to assign the contents of the input buffer to a variable when the field is shorter than expected.

 

Use MISSOVER if the last field or fields might be missing and you want SAS to assign missing values to the corresponding variable.

 

Behavior is similar for many simple read items.

Example of without an option and with:

data defaulthave;
input FirstName $ LastName $ @;
do i=1 to 4;
   input score  @;
   output;
end;
input;
drop i;
datalines;
Sally Mae    30 40 50 60 
John  Goe    30 40 50 60 
Matt  Miller 30 40 
Henry Mae    30 40 50 60 
;

data have;
infile datalines missover;
input FirstName $ LastName $ @;
do i=1 to 4;
   input score  @;
   output;
end;
input;
drop i;
datalines;
Sally Mae    30 40 50 60 
John  Goe    30 40 50 60 
Matt  Miller 30 40 
Henry Mae    30 40 50 60 
;

If you run the first data step above your log will show something like:

NOTE: Invalid data for score in line 262 1-5.
NOTE: Invalid data for score in line 262 7-9.
RULE:      ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+--
262        Henry Mae    30 40 50 60
FirstName=Matt LastName=Miller i=5 score=. _ERROR_=1 _N_=3
NOTE: SAS went to a new line when INPUT statement reached past the end of a line.

and the data will be incomplete. That note about "went to a new line" almost always means you have an issue between your expected data from the input statement(s) and the actual content.

 

The second data step yields what I think you would expect with two missing values on a record.

You can run the code with TRUNCOVER in place of MISSOVER to see what, if any difference, results.

 

Note: You are using list input. So if the "first" score is the one you think is missing the result will be read as the first actual score an the missing will appear at the end. If you need to know or keep a specific order of "missingness" then the solution shown by @PeterClemmensen would be a better choice.

Ksharp
Super User
data have;
infile datalines truncover;
input FirstName $ LastName $ value @;
do while(not missing(value));
 output;
 input value @;
end;

datalines;
Sally Mae    30 40 50 60 
John  Goe    30 40 50 60 
Matt  Miller 30 40 
Henry Mae    30 40 50 60 
;

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 8 replies
  • 880 views
  • 1 like
  • 4 in conversation