Barite | Level 11

## Retain vs. Retain 0

Can someone please explain nicely and with examples the difference between RETAIN and RETAIN 0? For example,

RETAIN var1;      vs.      RETAIN var1 0;

Many thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
Barite | Level 11

## Re: Retain vs. Retain 0

``````DATA demo;
LENGTH a b c d ac bc cc dc 8.;
RETAIN a ; *same as RETAIN a .;
RETAIN b 0;
RETAIN c 10;
*NOTE: doing nothing to variable d (default);

/* Initialization proceeds as follows */
ac = a + 1; *_N_ = 1: a = . (the value you provided initially);
*_N_ = 2: a = . (the value retained from previous step);
*_N_ = 3: a = 5 (the value retained from previous step);

bc = b + 1; *_N_ = 1: b = 0 (the value you provided initially);
*_N_ = 2: b = .	(the value retained from previous step);
*_N_ = 3: b = 5 (the value retained from previous step);

cc = c + 1; *_N_ = 1: c = 10 (the value you provided initially);
*_N_ = 2: c = .	(the value retained from previous step);
*_N_ = 3: c = 5 (the value retained from previous step);

dc = d + 1; *_N_ = 1: d = . (default behavior: initialized to . beginning every step);
*_N_ = 2: d = . (default behavior: initialized to . beginning every step);
*_N_ = 3: d = . (default behavior: initialized to . beginning every step);

INPUT a b c d;
DATALINES;
. . . .
5 5 5 5
. . . .
;
RUN;

PROC PRINT DATA = demo NOOBS;
RUN;``````

7 REPLIES 7
PROC Star

## Re: Retain vs. Retain 0

@pink_poodle wrote:

Can someone please explain nicely and with examples the difference between RETAIN and RETAIN 0? For example,

RETAIN var1;      vs.      RETAIN var1 0;

Many thanks!

Your second version provides an initial value of 0.  Otherwise it is initialized to a missing value (blanks for character vars, . for numerics):

``````data _null_;
length x \$5;
retain x;
retain y 0;
retain z;
put (_all_) (=);
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

--------------------------
Barite | Level 11

## Re: Retain vs. Retain 0

I get this in the log:
NOTE: Variable x is uninitialized.
NOTE: Variable z is uninitialized.
x= y=0 z=.
SAS Super FREQ

## Re: Retain vs. Retain 0

The documentation has this information. Read: https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lestmtsref/p0t2ac0tfzcgbjn112mu96hkgg9o.htm

From the doc: This RETAIN statement retains the values of nine variables and sets their initial values:
retain month1-month5 1 year 0 a b c 'XYZ';
The values of MONTH1 through MONTH5 are set initially to 1; YEAR is set to 0; variables A, B, and C are each set to the character value XYZ.
If you omit initial-value, the initial value is missing.
Super User

## Re: Retain vs. Retain 0

When you use

``retain var1 ;``

It will retain var1, and set the initial value to missing.

If you want to set the initial value to 0 you would use:

``retain var1 0 ;``

If you code:

``````data want1 ;
set sashelp.class ;
retain counter  ;

put _n_= "before incrementing" counter= ;
counter=sum(counter,1) ;
put _n_= "after incrementing" counter= ;
run ;``````

You will see that the first PUT statement shows counter has a missing value.

If you code:

``````data want2 ;
set sashelp.class ;
retain counter 0;

put _n_= "before incrementing" counter= ;
counter=sum(counter,1) ;
put _n_= "after incrementing" counter= ;
run ;``````

The first PUT statement will show counter has the value 0.

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Super User

## Re: Retain vs. Retain 0

RETAIN on its own does not set any attributes of the variable. RETAIN 0 defines it as numeric and initializes it to zero.

Barite | Level 11

## Re: Retain vs. Retain 0

``````DATA demo;
LENGTH a b c d ac bc cc dc 8.;
RETAIN a ; *same as RETAIN a .;
RETAIN b 0;
RETAIN c 10;
*NOTE: doing nothing to variable d (default);

/* Initialization proceeds as follows */
ac = a + 1; *_N_ = 1: a = . (the value you provided initially);
*_N_ = 2: a = . (the value retained from previous step);
*_N_ = 3: a = 5 (the value retained from previous step);

bc = b + 1; *_N_ = 1: b = 0 (the value you provided initially);
*_N_ = 2: b = .	(the value retained from previous step);
*_N_ = 3: b = 5 (the value retained from previous step);

cc = c + 1; *_N_ = 1: c = 10 (the value you provided initially);
*_N_ = 2: c = .	(the value retained from previous step);
*_N_ = 3: c = 5 (the value retained from previous step);

dc = d + 1; *_N_ = 1: d = . (default behavior: initialized to . beginning every step);
*_N_ = 2: d = . (default behavior: initialized to . beginning every step);
*_N_ = 3: d = . (default behavior: initialized to . beginning every step);

INPUT a b c d;
DATALINES;
. . . .
5 5 5 5
. . . .
;
RUN;

PROC PRINT DATA = demo NOOBS;
RUN;``````

Super User

## Re: Retain vs. Retain 0

You should normally avoid using RETAIN for variables that you are actually READING in with an INPUT statement.  The only case where that makes sense is when the INPUT statement is executed CONDITIONALLY so values are only read in some times so that the retained value can be used in the other cases.

A better way to see what is happening is to look at the values during the data step itself.

``````DATA demo;
LENGTH a b c d ac bc cc dc 8.;
RETAIN a ; *same as RETAIN a .;
RETAIN b 0;
RETAIN c 10;
*NOTE: doing nothing to variable d (default);
if _n_=1 then put '  A  B  C  D AC BC CC DC';
put _n_=;
put (_all_) (3.) ' <- START';
/* Initialization proceeds as follows */
ac = a + 1; *_N_ = 1: a = . (the value you provided initially);
*_N_ = 2: a = . (the value retained from previous step);
*_N_ = 3: a = 5 (the value retained from previous step);

bc = b + 1; *_N_ = 1: b = 0 (the value you provided initially);
*_N_ = 2: b = .	(the value retained from previous step);
*_N_ = 3: b = 5 (the value retained from previous step);

cc = c + 1; *_N_ = 1: c = 10 (the value you provided initially);
*_N_ = 2: c = .	(the value retained from previous step);
*_N_ = 3: c = 5 (the value retained from previous step);

dc = d + 1; *_N_ = 1: d = . (default behavior: initialized to . beginning every step);
*_N_ = 2: d = . (default behavior: initialized to . beginning every step);
*_N_ = 3: d = . (default behavior: initialized to . beginning every step);
put (_all_) (3.) ' <- AFTER IF';
INPUT a b c d;
put (_all_) (3.) ' <- AFTER INPUT';
DATALINES;
. . . .
5 5 5 5
. . . .
;``````

Result

```  A  B  C  D AC BC CC DC
_N_=1
.  0 10  .  .  .  .  . <- START
.  0 10  .  .  1 11  . <- AFTER IF
.  .  .  .  .  1 11  . <- AFTER INPUT
_N_=2
.  .  .  .  .  .  .  . <- START
.  .  .  .  .  .  .  . <- AFTER IF
5  5  5  5  .  .  .  . <- AFTER INPUT
_N_=3
5  5  5  .  .  .  .  . <- START
5  5  5  .  6  6  6  . <- AFTER IF
.  .  .  .  6  6  6  . <- AFTER INPUT
_N_=4
.  .  .  .  .  .  .  . <- START
.  .  .  .  .  .  .  . <- AFTER IF
```

Notice also that the data steps ends on the 4th iteration when the INPUT statement reads past the end of the datalines.

Discussion stats
• 7 replies
• 532 views
• 7 likes
• 6 in conversation