- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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).