BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
pink_poodle
Barite | Level 11

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
pink_poodle
Barite | Level 11
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;

pink_poodle_0-1708629462234.png

 

View solution in original post

7 REPLIES 7
mkeintz
PROC Star

@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

--------------------------
pink_poodle
Barite | Level 11
I get this in the log:
NOTE: Variable x is uninitialized.
NOTE: Variable z is uninitialized.
x= y=0 z=.
JosvanderVelden
SAS Super FREQ
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.
Quentin
Super User

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: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
pink_poodle
Barite | Level 11
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;

pink_poodle_0-1708629462234.png

 

Tom
Super User Tom
Super User

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.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 7 replies
  • 690 views
  • 7 likes
  • 6 in conversation