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;
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.

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.

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.
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;
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.
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-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

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
  • 600 views
  • 5 likes
  • 5 in conversation