PUT Statement
Writes lines to the SAS log, to the Results window, or to an external location that is specified in the most recent FILE statement.
| Valid in: | DATA step |
| Categories: | CAS |
| File-Handling | |
| Type: | Executable |
Syntax
Without Arguments
-
writes the current output line to the current location, even if the current output line is blank
-
releases an output line that is being held with a trailing @ by a previous PUT statement.
Arguments
specification(s)
specifies what is written, how it is written, and where it is written. The specification can include
variable
specifies the variable whose value is written.
(variable-list)
specifies a list of variables whose values are written.
| Requirement | The (format-list) must follow the (variable-list). |
| See | PUT Statement, Formatted |
'character-string'
specifies a string of text, enclosed in quotation marks, to write.
| Tips | To write a hexadecimal string in EBCDIC or ASCII, follow
the ending quotation mark with an x.
|
| If you use single quotation marks ('') or double quotation marks ("") together (with no space in between them) as the string of text, SAS generate a single quotation mark ( ') or double quotation mark ("), respectively. | |
| See | List Output |
| Example | This statement writes HELLO when the hexadecimal string
is converted to ASCII characters: put '68656C6C6F'x; |
n*
specifies to repeat n times the subsequent character string.
| Example | This statement writes a line of 132 underscores. put 132*'_'; |
| Example | Underlining Text |
pointer-control
moves the output pointer to a specified line or column in the output buffer.
| See | Column Pointer Controls |
| Line Pointer Controls |
column-specifications
specifies which columns of the output line the values are written.
| See | Column Output |
| Example | Moving the Pointer within a Page |
format.
specifies a format to use when the variable values are written.
| See | Formatted Output |
| Example | Using Multiple Output Styles in One PUT Statement |
(format-list)
specifies a list of formats to use when the values of the preceding list of variables are written.
| Restriction | The (format-list) must follow the (variable-list). |
| See | PUT Statement, Formatted |
_INFILE_
writes the last input data record that is read either from the current input file or from the data lines that follow a DATELINES statement.
| Tips | _INFILE_ is an automatic variable that references the current INPUT buffer. You can use this automatic variable in other SAS statements. |
| If the most recent INPUT statement uses line-pointer controls to read multiple input data records, PUT _INFILE_ writes only the record that the input pointer is positioned on. | |
| Example | This PUT statement writes all the values of the first
input data record: input #3 score #1 name $ 6-23; put _infile_; |
| Example | Writing the Current Input Record to the Log |
_ALL_
writes the values of all variables, which includes automatic variables, that are defined in the current DATA step by using named output.
| See | Named Output |
_ODS_
moves data values for all columns (as defined by the ODS option in the FILE statement) into a special buffer, from which it is eventually written to the data component. The ODS option in the FILE statement defines the structure of the data component that holds the results of the DATA step.
| Restrictions | When writing to ODS, the PUT statement does not support VARCHAR variables in SAS Viya. |
| Use _ODS_ only if you have previously specified the ODS option in the FILE statement. | |
| Interaction | _ODS_ writes data to a specific column only if a PUT statement has not already specified a variable for that column with a column pointer. That is, a variable specification for a column overrides the _ODS_ option. |
| Tip | You can use the _ODS_ specification in conjunction with variable specifications and column pointers, and it can appear anywhere in a PUT statement. |
@|@@
holds an output line for the execution of the next PUT statement even across iterations of the DATA step. These line-hold specifiers are called trailing @ and double trailing @.
| Restriction | The trailing @ or double trailing @ must be the last item in the PUT statement. |
| Tip | Use an @ or @@ to hold the pointer at its current location. The next PUT statement that executes writes to the same output line rather than to a new output line. |
| See | Using Line-Hold Specifiers |
| Example | Holding and Releasing Output Lines |
Column Pointer Controls
@n
moves the pointer to column n.
| Range | a positive integer |
| Example | @15 moves the pointer to column 15 before the value
of NAME is written: put @15 name $10.; |
| Examples | Moving the Pointer within a Page and Underlining Text |
@numeric-variable
moves the pointer to the column given by the value of numeric-variable.
| Range | a positive integer |
| Tip | If n is not an integer, SAS truncates the decimal portion and uses only the integer value. If n is zero or negative, the pointer moves to column 1. |
| Example | The value of the variable A moves the pointer to column
15 before the value of NAME is written: a=15; put @a name $10.; |
| Example | Moving the Pointer within a Page |
@(expression)
moves the pointer to the column that is given by the value of expression.
| Range | a positive integer |
| Tip | If the value of expression is not an integer, SAS truncates the decimal value and uses only the integer value. If it is zero, the pointer moves to column 1. |
| Example | The result of the expression moves the pointer to
column 15 before the value of NAME is written: b=5; put @(b*3) name $10.; |
+n
moves the pointer n columns.
| Range | a positive integer or zero |
| Tip | If n is not an integer, SAS truncates the decimal portion and uses only the integer value. |
| Example | This statement moves the pointer to column 23, writes
a value of LENGTH in columns 23 through 26, advances the pointer
five columns, and writes the value of WIDTH in columns 32 through
35: put @23 length 4. +5 width 4.; |
+numeric-variable
moves the pointer the number of columns given by the value of numeric-variable.
| Range | a positive or negative integer or zero |
| Tip | If numeric-variable is not an integer, SAS truncates the decimal value and uses only the integer value. If numeric-variable is negative, the pointer moves backward. If the current column position becomes less than 1, the pointer moves to column 1. If the value is zero, the pointer does not move. If the value is greater than the length of the output buffer, the current line is written out and the pointer moves to column 1 on the next line. |
+(expression)
moves the pointer the number of columns given by expression.
| Range | expression must result in an integer |
| Tip | If expression is not an integer, SAS truncates the decimal value and uses only the integer value. If expression is negative, the pointer moves backward. If the current column position becomes less than 1, the pointer moves to column 1. If the value is zero, the pointer does not move. If the value is greater than the length of the output buffer, the current line is written out and the pointer moves to column 1 on the next line. |
| Example | Moving the Pointer within a Page |
Line Pointer Controls
#n
moves the pointer to line n and column 1.
| Range | a positive integer |
| Example | The #2 moves the pointer to the second line before
the value of ID is written in columns 3 and 4: put @12 name $10. #2 id 3-4; |
#numeric-variable
moves the pointer to the line given by the value of numeric-variable and to column 1.
| Range | a positive integer |
| Tip | If the value of numeric-variable is not an integer, SAS truncates the decimal value and uses only the integer value. |
#(expression)
moves the pointer to the line that is given by the value of expression and to column 1.
| Range | Expression must result in a positive integer. |
| Tip | If the value of expression is not an integer, SAS truncates the decimal value and uses only the integer value. |
/
advances the pointer to column 1 of the next line.
| Note | If you try to use one or more “/” line pointer controls to add blank lines to the SAS log, SAS suppresses the blank lines. For other forms of output, the blank lines are produced. |
| Example | The values for NAME and AGE are written on one line,
and then the pointer moves to the second line to write the value of
ID in columns 3 and 4: put name age / id 3-4; |
| Example | Moving the Pointer to a New Page |
OVERPRINT
causes the values that follow the keyword OVERPRINT to print on the most recently written output line.
| Requirement | You must direct the output to a file. Set the N= option in the FILE statement to 1 and direct the PUT statements to a file. |
| Tips | OVERPRINT has no effect on lines that are written to a display. |
| Use OVERPRINT in combination with column pointer and line pointer controls to overprint text. | |
| Example | This statement overprints underscores, starting in
column 15, which underlines the title: put @15 'Report Title' overprint
@15 '____________'; |
| Example | Underlining Text |
_BLANKPAGE_
advances the pointer to the first line of a new page, even when the pointer is positioned on the first line and the first column of a new page.
| Tip | If the current output file contains carriage-control characters, _BLANKPAGE_ produces output lines that contain the appropriate carriage-control character. |
| Example | Moving the Pointer to a New Page |
_PAGE_
advances the pointer to the first line of a new page. SAS automatically begins a new page when a line exceeds the current PAGESIZE= value.
| Tips | If the current output file is printed, _PAGE_ produces an output line that contains the appropriate carriage-control character. _PAGE_ has no effect on a file that is not printed. |
| If you specify FILE PRINT in an interactive SAS session, then the Results window interprets the form-feed control characters as page breaks, and they are removed from the output. The resulting file is a flat file without page break characters. If a file needs to contain the form-feed characters, then the FILE statement should include a physical file location and the PRINT option. | |
| Example | Moving the Pointer to a New Page |
Details
When to Use PUT
Output Styles
Overview of Output Styles
-
column
-
list (simple and modified)
-
formatted
-
named
Column Output
put name 6-15 age 17-19;
----+----1----+----2----+
Peterson 21
Morgan 17List Output
put name age;
----+----1----+----2----+ Peterson 21 Morgan 17
Formatted Output
put name $char10. age 2. +1 date mmddyy10.;
----+----1----+----2----+ Peterson 21 07/18/1999 Morgan 17 11/12/1999
Named Output
put name= age=;
----+----1----+----2----+ name=Peterson age=21 name=Morgan age=17
Using Multiple Output Styles in a Single PUT Statement
put name 'on ' date mmddyy8. ' weighs '
startwght +(-1) '.' idno= 40-45;Avoiding a Common Error When Writing Both a Character Constant and a Variable
put 'Player:' name1 'Player:' name2 'Player:' name3;
|
Starting Letter of Variable
|
Represents
|
Examples
|
|---|---|---|
|
b
|
bit testing constant
|
'00100000'b
|
|
d
|
date constant
|
'01jan04'd
|
|
dt
|
datetime constant
|
'18jan2003:9:27:05am'dt
|
|
n
|
name literal
|
'My Table'n
|
|
t
|
time constant
|
'9:25:19pm't
|
|
x
|
hexadecimal notation
|
'534153'x
|
Pointer Controls
|
Pointer Controls
|
Relative
|
Absolute
|
|---|---|---|
|
column pointer controls
|
+n
|
@n
|
|
+numeric-variable
|
@numeric-variable
| |
|
+(expression)
|
@(expression)
| |
|
line pointer controls
|
/ , _PAGE_ ,
_BLANKPAGE_
|
#n
#numeric-variable
#(expression)
|
|
OVERPRINT
|
none
| |
|
line-hold specifiers
|
@
|
(not applicable)
|
|
@@
|
(not applicable)
|
Using Line-Hold Specifiers
-
more than one PUT statement writes to the same output line
-
a PUT statement writes values from more than one observation to the same output line.
-
a PUT statement without a trailing @
-
a PUT statement that uses _BLANKPAGE_ or _PAGE_
-
the end of the current line (determined by the current value of the LRECL= or LINESIZE= option in the FILE statement, if specified, or the LINESIZE= system option)
-
the end of the last iteration of the DATA step.
Pointer Location After a Value Is Written
-
PUT _BLANKPAGE_ writes a blank page and moves the pointer to the top of the next page.
-
PUT _PAGE_ leaves the pointer in the same location.
When the Pointer Goes Past the End of a Line
-
the value of the LINESIZE= option in the current FILE statement
-
the value of the LINESIZE= system option (for the Results window)
-
the LRECL= option in the current FILE statement (for external files).
-
a + pointer control with a value that moves the pointer to a column beyond the current line length
-
a column range that exceeds the current line length (for example, PUT X 90 – 100 when the current line length is 80)
-
a variable value or character string that does not fit in the space that remains on the current output line.
Arrays
-
@(array-name{i})
-
+(array-name{i})
-
#(array-name{i})
PUT array-name{*}; PUT array-name{*}(format|format.list)
Comparisons
-
The PUT statement writes variable values and character strings to the SAS log or to an external location while the INPUT statement reads raw data in external files or data lines entered instream.
-
Both the INPUT and the PUT statements use the trailing @ and double trailing @ line-hold specifiers to hold the current line in the input or output buffer, respectively. In an INPUT statement, a double trailing @ holds a line in the input buffer from one iteration of the DATA step to the next. In a PUT statement, however, a trailing @ has the same effect as a double trailing @; both hold a line across iterations of the DATA step.
-
Both the PUT and OUTPUT statements create output in a DATA step. The PUT statement uses an output buffer and writes output lines to an external location, the SAS log, or your monitor. The OUTPUT statement uses the program data vector and writes observations to a SAS data set.
Examples
Example 1: Using Multiple Output Styles in One PUT Statement
data club1;
input idno name $ startwght date : date7.;
put name 'on ' date mmddyy8. ' weighs '
startwght +(-1) '.' idno= 32-40;
datalines;
032 David 180 25nov99
049 Amelia 145 25nov99
219 Alan 210 12nov99
;|
Variables
|
Output Style
| |
|---|---|---|
|
NAME, STARTWGHT
|
list output
| |
|
DATE
|
formatted output
| |
|
IDNO
|
named output
| |
----+----1----+----2----+----3----+----4 David on 11/25/99 weighs 180. idno=1032 Amelia on 11/25/99 weighs 145. idno=1049 Alan on 11/12/99 weighs 210. idno=1219
Example 2: Moving the Pointer within a Page
-
To move the pointer to a specific column, use @ followed by the column number, variable, or expression whose value is that column number. For example, this statement moves the pointer to column 15 and writes the value of TOTAL SALES using list output:
put @15 totalsales;
This PUT statement moves the pointer to the value that is specified in COLUMN and writes the value of TOTALSALES with the COMMA6 format:data _null_; set carsales; column=15; put @column totalsales comma6.; run;
-
This program shows two techniques to move the pointer backward:
data carsales; input item $10. jan : comma5. feb : comma5. mar : comma5.; saleqtr1=sum(jan,feb,mar); /* an expression moves pointer backward */ put '1st qtr sales for ' item 'is ' saleqtr1 : comma6. +(-1) '.'; /* a numeric variable with a negative value moves pointer backward. */ x=-1; put '1st qtr sales for ' item 'is ' saleqtr1 : comma5. +x '.'; datalines; trucks 1,382 2,789 3,556 vans 1,265 2,543 3,987 sedans 2,391 3,011 3,658 ;Because the value of SALEQTR1 is written with modified list output, the pointer moves automatically two spaces. For more information, see How Modified List Output and Formatted Output Differ. To remove the unwanted blank that occurs between the value and the period, move the pointer backward by one space.The program writes these lines to the SAS log:----+----1----+----2----+----3----+----4 st qtr sales for trucks is 7,727. st qtr sales for trucks is 7,727. st qtr sales for vans is 7,795. st qtr sales for vans is 7,795. st qtr sales for sedans is 9,060. st qtr sales for sedans is 9,060.
Note: The ruled line is for illustrative purposes only; the PUT statement does not generate it. -
This program uses a PUT statement with the / line pointer control to advance to the next output line:
data _null_; set carsales end=lastrec; totalsales+saleqtr1; if lastrec then put @2 'Total Sales for 1st Qtr' / totalsales 10-15; run;After the DATA step calculates TOTALSALES using all the observations in the CARSALES data set, the PUT statement executes. It writes a character string beginning in column 2 and moves to the next line to write the value of TOTALSALES in columns 10 through 15:----+----1----+----2----+----3 Total Sales for 1st Qtr 24582Note: The ruled line is for illustrative purposes only; the PUT statement does not generate it.
Example 3: Moving the Pointer to a New Page
title1;
data statepop;
input state $ cityp90 ncityp90 region @@;
label cityp90= '1990 metropolitan population
(million)'
ncityp90='1990 nonmetropolitan population
(million)'
region= 'Geographic region';
datalines;
ME .443 .785 1 NH .659 .450 1
VT .152 .411 1 MA 5.788 .229 1
RI .938 .065 1 CT 3.148 .140 1
NY 16.515 1.475 1 NJ 7.730 .A 1
PA 10.083 1.799 1 DE .553 .113 2
MD 4.439 .343 2 DC .607 . 2
VA 4.773 1.414 2 WV .748 1.045 2
NC 4.376 2.253 2 SC 2.423 1.064 2
GA 4.352 2.127 2 FL 12.023 .915 2
KY 1.780 1.906 2 TN 3.298 1.579 2
AL 2.710 1.331 2 MS .776 1.798 2
AR 1.040 1.311 2 LA 3.160 1.060 2
OK 1.870 1.276 2 TX 14.166 2.821 2
OH 8.826 2.021 3 IN 3.962 1.582 3
IL 9.574 1.857 3 MI 7.698 1.598 3
WI 3.331 1.561 3 MN 3.011 1.364 3
IA 1.200 1.577 3 MO 3.491 1.626 3
ND .257 .381 3 SD .221 .475 3
NE .787 .791 3 KS 1.333 1.145 3
MT .191 .608 4 ID .296 .711 4
WY .134 .319 4 CO 2.686 .608 4
NM .842 .673 4 AZ 3.106 .559 4
UT 1.336 .387 4 NV 1.014 .183 4
WA 4.036 .830 4 OR 1.985 .858 4
CA 28.799 .961 4 AK .226 .324 4
HI .836 .272 4
;
proc format;
value regfmt 1='Northeast'
2='South'
3='Midwest'
4='West';
run;
data _null_;
set statepop;
by region;
pop90=sum(cityp90,ncityp90);
file print;
put state 1-2 @5 pop90 7.3 ' million';
if first.region then
regioncitypop=0; /* new region */
regioncitypop+cityp90;
if last.region then
do;
put // '1990 US CENSUS for ' region regfmt.
/ 'Total Urban Population: '
regioncitypop' million' _page_;
end;
run;1 ME 1.228 million NH 1.109 million VT 0.563 million MA 6.017 million RI 1.003 million CT 3.288 million NY 17.990 million NJ 7.730 million PA 11.882 million 1990 US CENSUS for Northeast Total Urban Population: 45.456 million
Example 4: Underlining Text
data _null_;
input idno name $ startwght;
file file-specification print;
put name 1-10 @15 startwght 3.;
if startwght > 200 then
put overprint @15 '___';
datalines;
032 David 180
049 Amelia 145
219 Alan 210
; put @5 name $8. overprint @5 8*'_'
/ @20 address;Example 5: Holding and Releasing Output Lines
data _null_;
input idno name $ startwght 3.;
put name @;
if startwght ne . then
put @15 startwght;
else put;
datalines;
032 David 180
049 Amelia 145
126 Monica
219 Alan 210
;-
the trailing @ in the first PUT statement holds the current output line after the value of NAME is written
-
if the condition is met in the IF-THEN statement, the second PUT statement writes the value of STARTWGHT and releases the current output line
-
if the condition is not met, the second PUT never executes. Instead, the ELSE PUT statement executes. The ELSE PUT statement releases the output line and positions the output pointer at column 1 in the output buffer.
----+----1----+----2 David 180 Amelia 145 Monica Alan 210
Example 6: Writing the Current Input Record to the Log
data team;
input id team $ score1 score2;
if id le 1000 then
do;
put _infile_;
delete;
end;
datalines;
032 red 180 165
049 yellow 145 124
219 red 210 192
;----+----1----+----2 219 red 210 192
Example 7: Avoiding a Common Error When Writing a Character Constant Followed by a Variable
data _null_; n=5; nvar1=1; var1=7; put @1 'n' nvar1 'n'; run;
----+----1----+----2 n1 n
put @1 'n'nvar1'n';
----+----1----+----2 5 7 n
put @1 'n' nvar1 +(-1) 'n';
----+----1----+----2 n1n
Example 8: Creating Multi-Column Output
/*
* Use #i and @j to position name and weight information into
* four columns in column-major order. That is print down column 1
* first, then print down column 2, etc.
* This example highlights the need to specify # before @ because
* # sets the column pointer to 1.
*/
data _null_;
file print n=ps notitles header=hd;
do i = 1 to 80 by 20;
do j = 1 to ceil(num_students/4);
set sashelp.class nobs=num_students;
put #(j+3) @i name $8. '-' +1 weight 5.1;
end;
end;
stop;
hd:
put @26 'Student Weight in Pounds' / @26 24*'-';
return;
run; Student Weight in Pounds
------------------------
Alfred - 112.5 James - 83.0 Joyce - 50.5 Robert - 128.0
Alice - 84.0 Jane - 84.5 Judy - 90.0 Ronald - 133.0
Barbara - 98.0 Janet - 112.5 Louise - 77.0 Thomas - 85.0
Carol - 102.5 Jeffrey - 84.0 Mary - 112.0 William - 112.0
Henry - 102.5 John - 99.5 Philip - 150.0