DATA Step, Macro, Functions and more

code for a factorial calcuator

Accepted Solution Solved
Reply
Super Contributor
Posts: 441
Accepted Solution

code for a factorial calcuator

Hi,

 

I am trying to create a table of factorials from 1 to 10.

 

The code that I wrote is:

 

data have;
do number = 1 to 10;

  if number = 1 then factorial = 1;
  else  factorial = number * lag (factorial);
  output;
end;

run;

But the result that I am getting is:

 

SAS Output

Obs number factorial
1 1 1
2 2 .
3 3 3
4 4 .
5 5 15
6 6 .
7 7 105
8 8 .
9 9 945
10 10 .

 

So I do get factorials, but only for the odd numbers. This is really strange because I can't figure out why this is happening. Please let me know what code intricacy is at play here!

 

Thanks

PS: how do I get back to left side writing?


Accepted Solutions
Solution
‎03-18-2017 12:26 PM
PROC Star
Posts: 7,492

Re: code for a factorial calcuator

As for what you were doing wrong .. you will always get unexpected results if lag is used conditionally.

 

However, in this case, you don't need either lag or retain as you're not going through automatic iterations. The following would do the same as the fact function:

 

data test;
  do number = 1 to 10;
    if number eq 1 then factorial=1;
    else factorial=factorial*number;
    output;
  end;
run;

Art, CEO, AnalystFinder.com

View solution in original post


All Replies
PROC Star
Posts: 7,492

Re: code for a factorial calcuator

I'll try to answer your question in two separate posts. First, to get what you want, I think you'll find this a lot easier:

 

data have;
  do number = 1 to 10;
    factorial=fact(number);
    output;
  end;
run;

Also, to get code right justified in posts use the {i} icon

 

Art, CEO, AnalystFinder.com

Solution
‎03-18-2017 12:26 PM
PROC Star
Posts: 7,492

Re: code for a factorial calcuator

As for what you were doing wrong .. you will always get unexpected results if lag is used conditionally.

 

However, in this case, you don't need either lag or retain as you're not going through automatic iterations. The following would do the same as the fact function:

 

data test;
  do number = 1 to 10;
    if number eq 1 then factorial=1;
    else factorial=factorial*number;
    output;
  end;
run;

Art, CEO, AnalystFinder.com

Super Contributor
Posts: 441

Re: code for a factorial calcuator

Hi art297,

 

Thanks for the solution!

 

From what I understand, its as if there is an "automatic retain" for the variable "factorial", and I suppose that this is the case for any variable for whose calculation I want to use its "lagged" value. But in this case does it mean that it is not possible to use a second or higher degree of lag when looping?

 

Also, I did a small modification to the code to include the variable "number2":

 

data test;
  do number = 1 to 10;
    if number eq 1 then do; factorial=1; number2=1; end;
    else do; factorial=factorial*number ; number2=factorial+number2;end;
    output;
  end;
run;

When I run the code I see that the variable "number2" is the sum of the "lagged" number2 and the "same iteration" variable "factorial". So again, the "automatic retain" is appleid to number2 because it is used in the calculation of number2, but for the other variables its a normal "same iteration" level operation.

PROC Star
Posts: 7,492

Re: code for a factorial calcuator

Not sure if I can explain this sufficiently in a quick post. Nothing about retain or lag, in the SAS sense of the terms, is applicable here.

 

Retain only applies to what happens to a variable when, during a normal data step, sas reads another record.

 

Nothing like that occurs in your example thus, in the SAS sense of the term, no automatic iterations occur.

 

The variables keep their values because nothing is in the code to reset them.

 

Art, CEO, AnalystFinder.com

 

Super User
Posts: 11,343

Re: code for a factorial calcuator

data have;

   do i = 1 to 10;

       factorial = fact(i);

       output;

   end;

run;

 

Note the SAS has a factorial function built in (and a log of the Factorial).

 

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 5 replies
  • 222 views
  • 7 likes
  • 3 in conversation