## code for a factorial calcuator

Solved
Super Contributor
Posts: 459

# 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: 8,150

## 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

All Replies
PROC Star
Posts: 8,150

## 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: 8,150

## 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: 459

## 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: 8,150

## 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: 13,358

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