Hi everyone,
I'm facing an issue when doing an itrative sum using factorials. This is the first time I use both an iterative sum and the FACT function so I guess there are a lot of things wrong in my code.
Want I want is the formula I hereby attached.
Here it its:
data lsv.right;
set lsv.left;
do i=0 to i=(buy+sell);
right = ((fact(buy+sell)/ (fact(i)+fact(Buy+sell-i)))*(i/(buy+sell))*((1-Pt)**(Buy+sell-i))*abs((i/(buy+sell)-Pt)))+ right;
end;
run;
Here is a sample of data I have. BUy and sell are integers.
Buy | Sell | Pt | Right |
3 | 4 | 2,7865 | |
8 | 10 | 6,78783 |
Could you please help me with it ?
Thank you
Hi,
So what is the problem with it, is it giving an Error/Warning or not giving you the result you expect. If you are not getting the result you expect then break the formula down into parts, e.g.:
data ...;
temp1=fact(buy+sell);
temp2=temp1 /....
If it is error/warning then post the log.
Here is the log error message
NOTE: Invalid argument to function FACT at line 36 column 11.
NOTE: Invalid argument to function FACT at line 36 column 36.
NOTE: Invalid argument to function FACT at line 36 column 11.
NOTE: Invalid argument to function FACT at line 36 column 36.
Well, I would first check that all your variables are numeric (I suspect this is your problem). Buy, sell and pt. If not then you are passing a character to a function which is requiring a numeric. I would also re-iterate to break the formula up so you have a bit more clarity of what is going on (this works for me), like:
data have;
attrib Buy Sell Pt format=best.;
buy=3; sell=4; pt=27865; output;
buy=8; sell=10; pt=678783; output;
run;
data want;
set have;
bs=buy + sell;
right=0;
do i=0 to bs;
calc1=(fact(bs) / (fact(i) + fact(bs-i)));
calc2=calc1 * (i/(bs)) * ((1-Pt)**(bs-i)) * abs((i/(bs)-Pt));
right=calc2 + right;
end;
run;
Wild guess, that 'buy' and/or 'sell' are character variables in dataset lsv.left as mentioned by , judging by the location in the line for these NOTEs..
You may wish to consider reparameterizing and using LFACT (log of the factorial) in order to avoid a noncomputable result for moderately large arguments.
Steve Denham
I used your code and I made sure that I treat with numeric variables. I create a num variable n that is the sum of buy and sell. But it still shows the same log error
Proc SQL;
alter table lsv.left
add n num label='n';
Proc SQL;
update lsv.left
set n=buy+sell;
data lsv.right;
set lsv.left;
right=0;
do i=0 to i=n;
calc1=(fact(n) / (fact(i) * fact(n-i)));
calc2=calc1 * (i/(n)) * ((1-Pt)**(n-i)) * abs((i/(n)-Pt));
right=calc2 + right;
end;
run;
In your code you have:
do I=0 to I=n;
This is incorrect, you want a range, so I=0 to n;
Thank you, I corrected it and nows the log error message becomes
Invalid DO loop control information, either the INITIAL or TO expression is missing or the
BY expression is missing, zero, or invalid.
Check what N in lsv.left as it sound like that is not being create properly. So do this:
Run the first SQL statement, check the lsv.left. Does this look correct.
Run the second SQL statement, check the lsv.left table looks correct.
I did it and there actually was a problem. The fact is that n was worth '.' when there were a buy or sell =0. So I corrected it this way
Proc SQL;
update lsv.left
set n=buy where sell=.;
Proc SQL;
Update lsv.left
set n=sell where buy=.;
But I still have the same error message
Could you post some test data of lsv.left after the two proc sql statements have run. I suspect you still have a . or missing in your data i.e. what happens if both buy and sell are missing, then that row should be removed as the procedures cannot work on that data.
Maybe get rid of the SQL part and just add a clause in your datastep:
data lsv.right;
set lsv.left;
right=0;
if buy ne . or sell ne . then do;
if buy=. then n=sell;
else n=buy;
do i=0 to i=n;
calc1=(fact(n) / (fact(i) * fact(n-i)));
calc2=calc1 * (i/(n)) * ((1-Pt)**(n-i)) * abs((i/(n)-Pt));
right=calc2 + right;
end;
end;
run;
Thanks a lot ! YOu were right. One row had both sell and buy equal to .
i deleted it and now it's working, thanks a lot !
Unfortunately i'm still facing an issue I can't solve; The value I otain for right is always >1 and sometimes superhigh. In actual facts this formula always lead to a result <1.
FYI: the input Pt is always around 0,5
Do you have an idea of the problem in the code ?
Sorry, am a code monkey not a stato, its all greek to me. Maybe post a question in the stats section.
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 25. Read more here about why you should contribute and what is in it for you!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.