2.5 Raw Data Ingestion with INFILE and INPUT Statements
Key Takeaways
- The INFILE statement identifies an external raw data file to be read within a DATA step, supporting options like DLM=, DSD, MISSOVER, TRUNCOVER, FIRSTOBS=, and OBS=.
- The DSD (Delimiter-Sensitive Data) option treats consecutive delimiters as missing values, removes surrounding quotation marks from text, and sets the default delimiter to a comma.
- MISSOVER prevents SAS from moving to the next line when a raw record ends prematurely, filling remaining INPUT variables with missing values.
- TRUNCOVER forces SAS to read partial field values at the end of a line up to the line boundary without jumping to the next line.
- The trailing single @ holds an input record for further processing within the current iteration, while the trailing double @@ holds a record across multiple DATA step iterations.
2.5 Raw Data Ingestion with INFILE and INPUT Statements
While PROC IMPORT provides quick automatic file ingestion, SAS Base programmers must master the INFILE and INPUT statements inside the DATA step for complete control over raw data parsing, complex informats, line-hold specifiers, and custom record structures.
1. The INFILE Statement & Essential Options
The INFILE statement specifies the external raw data file to be read by the INPUT statement in a DATA step.
data work.raw_ingest;
infile "C:\\Data\\raw_payroll.txt" dlm=',' dsd missover firstobs=2 obs=100;
input employee_id : $8. hire_date : mmddyy10. salary : dollar10.2;
run;
Key INFILE Statement Options
| Option | Description & Exam Application |
|---|---|
DLM='char' | Defines the field delimiter (e.g., dlm=',' or dlm='09'x for tabs). |
DSD | Delimiter-Sensitive Data. Performs three critical tasks:<br>1. Treats two consecutive delimiters as a missing value.<br>2. Strips surrounding quotes from character values.<br>3. Sets the default delimiter to a comma. |
FIRSTOBS=n | Specifies the line number of the first raw record to read (e.g., FIRSTOBS=2 skips header rows). |
OBS=n | Specifies the last line number of the raw record to read. |
MISSOVER | Prevents SAS from advancing to the next raw line if a record ends before all variables in the INPUT statement receive values; missing values (. or blank) are assigned instead. |
TRUNCOVER | Reads short or partial field values up to the end of the line without jumping to the next line or padding with blanks. Needed when using column/formatted input on variable-length lines. |
2. Line Boundary Handling: FLOWOVER vs. MISSOVER vs. TRUNCOVER
Understanding how SAS handles short records (records with fewer fields than variables in the INPUT statement) is critical for the exam:
FLOWOVER(the default): If anINPUTstatement reaches the end of a raw record before populating all variables, SAS automatically flows over to the next raw data line to read values for the remaining variables, consuming multiple physical lines per observation. The option is spelledFLOWOVER, notFLOW, and you rarely code it explicitly because it is already in effect.- MISSOVER: If an
INPUTstatement reaches the end of a raw record, SAS stops reading that record and sets all remaining unread variables to missing. - TRUNCOVER: Essential for formatted/column input. If a raw field is shorter than the informat width or truncated by the end of the line,
TRUNCOVERreads whatever characters exist up to the line boundary into the PDV, rather than setting the variable to missing or jumping to the next record.
/* Correct handling of short variable-length records */
data work.phone_directory;
infile "C:\\Data\\contacts.txt" missover;
input id $ name $ phone $ email $;
run;
3. INPUT Statement Styles
SAS supports four distinct styles of input in the INPUT statement:
1. List Input
Variables are separated by spaces or delimiters. Values are read sequentially.
input emp_id $ age department $ salary;
2. Column Input
Field locations are explicitly specified by column start and end positions. Spaces do not act as delimiters, allowing embedded blanks in string values.
input name $ 1-20 title $ 21-35 age 36-37;
3. Formatted Input
Combines pointer controls (@n, +n) with SAS informats (instructions on how to read raw data formats into standard numeric or character values).
input @1 emp_id $5. @7 hire_date mmddyy10. @18 salary dollar10.2;
4. Modified List Input
Uses informat modifiers (: or ~) alongside standard list input:
:Modifier: Instructs SAS to read past the raw data value until it encounters a delimiter, applying the specified informat width without being constrained by fixed column boundaries.~Modifier: Preserves quotes in string values when used withDSD.
/* Colon modifier allows reading formatted dates of varying field lengths */
input name : $20. start_date : date9. annual_pay : comma12.2;
4. Pointer Controls & Line-Hold Specifiers (@ and @@)
Pointer controls direct SAS where to read in the input buffer:
@n: Absolute column pointer (moves pointer directly to columnn).+n: Relative column pointer (moves pointer forwardncolumns)./: Line pointer control (advances pointer to column 1 of the next raw line).
Trailing Line-Hold Specifiers
+-------------------------------------------------------------------------+
| TRAILING LINE-HOLD SPECIFIERS |
+-------------------------------------------------------------------------+
| Single Trailing @ | Holds line in buffer for current DATA step iter. |
| Double Trailing @@ | Holds line in buffer across multiple iterations. |
+-------------------------------------------------------------------------+
Single Trailing @
Holds a raw record in the input buffer so that subsequent INPUT statements within the same iteration of the DATA step can execute conditional logic before reading the rest of the record.
data work.managers;
infile "C:\\Data\\staff.txt";
input type $ 1-1 @; /* Read type, hold record in buffer */
if type = 'M' then do;
input id $ 3-6 name $ 8-25 bonus dollar8.2;
output;
end;
run;
Double Trailing @@
Holds a raw record in the input buffer across multiple iterations of the DATA step. Used when a single line of raw data contains multiple observations.
/* Single line contains 3 observations: 101 25 102 30 103 28 */
data work.patient_ages;
infile datalines;
input patient_id age @@; /* Holds line across iterations until empty */
datalines;
101 25 102 30 103 28
104 42 105 39
;
run;
Which INFILE statement option treats two consecutive delimiters in a CSV file as a missing data value and automatically removes quotation marks around character values?
If a raw record contains fewer values than variables listed in the INPUT statement, what is the default FLOWOVER behavior of SAS if neither MISSOVER nor TRUNCOVER is specified?
Consider the following raw data line containing multiple records on one line: NY 45 LA 32 CHI 28 Which trailing line-hold specifier should be placed at the end of the INPUT statement to read all three observations into separate rows of the SAS dataset?
A SAS programmer uses formatted input to read fixed-width fields from a variable-length text file. Some lines end before the last character of a formatted field. Which INFILE option ensures SAS reads partial values up to the end of the line without jumping to the next line?