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

Hi,

Say I have a folllowing dataset:

 

data have;
	do i = 1 to 10;
		id = i;
		output;
	end;
	drop i;
run;
data have;
	set have;
	if id = 1 then var = 10;
run;


Now I want to fill empty rows in a recursive way, so that value of each row equals to the value of previous row multiplied by two (so the values are 20, 40, 80 etc)

 

I've tried to use retain statement in different ways but failed to achieve what I want.

 

Any help, please?

 

Best

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

But close.  Because you are retaining, you don't need lag. 

 

Consider something like:

 

data have;
  do i = 1 to 10;
    id = i;
    output;
  end;
  drop i;
run;

data want;
  set have;
retain var;
if id = 1 then var = 10; else var = var*2; put (id var)(=) ; run;
The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.

View solution in original post

7 REPLIES 7
Quentin
Super User

Please show the code you have tried, and describe whether you got errors or unexpected results.  It will help others help you.

The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
chris2377
Quartz | Level 8

Here you are @Quentin . But it's obviuosly wrong:

 

data my_try;
	set have;
 	retain var;
	var = lag(var)*2;
 run;
Quentin
Super User

But close.  Because you are retaining, you don't need lag. 

 

Consider something like:

 

data have;
  do i = 1 to 10;
    id = i;
    output;
  end;
  drop i;
run;

data want;
  set have;
retain var;
if id = 1 then var = 10; else var = var*2; put (id var)(=) ; run;
The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
ballardw
Super User

Since RETAIN is one of the most likely ways to accomplish this you should show what you tried and explain where it failed.

Note RETAIN gets reset to a value if it is already in the data set. So if you attempted to Retain Var from the last 'Have' set it would get reset to missing for all except the first observation.

 

I don't see any "empty rows" to "fill" with anything. You have created a data set with missing values for a specific Variable.

Perhaps this is what you are looking for.

data want;
   set have;
   retain tempvar;
   if var then tempvar=var;
   else do;
      var=2*tempvar;
      tempvar=var;
   end;
   drop tempvar;
run;

This will reset to the Var value when not missing, if there are any.

 


@chris2377 wrote:

Hi,

Say I have a folllowing dataset:

 

data have;
	do i = 1 to 10;
		id = i;
		output;
	end;
	drop i;
run;
data have;
	set have;
	if id = 1 then var = 10;
run;


Now I want to fill empty rows in a recursive way, so that value of each row equals to the value of previous row multiplied by two (so the values are 20, 40, 80 etc)

 

I've tried to use retain statement in different ways but failed to achieve what I want.

 

Any help, please?

 

Best

 

 


 

ghosh
Barite | Level 11

My understanding of recursion is a function that calls itself.   Thus a macro or proc fcmp would be ideal

proc fcmp outlib=work.funcs.myfunc;
function bytwo(n);
/* if n=1 then x=n; else x = n * 2; */
x=ifn(n=1,1,(n * 2)); return(x); endsub; quit; options cmplib=work.funcs; * Recursion example ; data allinone; do i = 1 to 10; var=bytwo(i); output; end; run; proc print; run;

ghosh_0-1662750144521.png

 

mkeintz
PROC Star

Use the RETAIN statement for two purposes: (1) to carry over values to subsequent observations, and (2) to initialize VAR to the desired value of 10 for the first observation.

 

Then output BEFORE doubling var to carry over to the next observation:

 

data have;
  do id = 1 to 10;
    output;
  end;
run;

data want;
  set have;
  retain var 10;
  output;
  var=2*var;
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

--------------------------
chris2377
Quartz | Level 8

Thanks @ballardw , @ghosh , @mkeintz for your suggestions as well

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 25. 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
  • 7 replies
  • 1031 views
  • 5 likes
  • 5 in conversation