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?
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
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
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
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.
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
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).
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 16. Read more here about why you should contribute and what is in it for you!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: