do loop within a macro - sas

The code below is returning the following error message:
Syntax error, expecting one of the following: a name, INPUT, PUT.
%macro run_calculation(amt, t, r);
data customer_value;
i=&r./100.;
do n=0 to t;
S=&amt.*[(1+ calculated i)^t - 1]/calculated i
end;
run;
%mend;
%run_calculation(amt=1000, t=8, r=5);
Expected output is S value at each t in a table.

Few comments:
You are missing a semi-colon ; when assigning S.
You don't have to use calculated i, use i directly.
Power operator in SAS is ** and not ^.
You point to t instead of the macro-variable &t. in the do loop statement.
You increment n, not t so you need to use n in your formula.
Use parenthesis, not brackets.
You are missing an explicit output statement in order to get S value for each n.
%macro run_calculation(amt, t, r);
data customer_value;
i=&r./100.;
do n=0 to &t.;
S=&amt.*((1+i)**n - 1)/i;
output;
end;
run;
%mend;
%run_calculation(amt=1000, t=8, r=5);
i n S
0.05 0 0
0.05 1 1000
0.05 2 2050
0.05 3 3152.5
0.05 4 4310.125
0.05 5 5525.63125
0.05 6 6801.9128125
0.05 7 8142.0084531
0.05 8 9549.1088758

Related

Looping through two lists in parallel

I have the following values
Time Value
3 0.03
6 0.04
9 0.05
12 0.06
As you can see, they move at steps of three and one respectively.
If I want to apply the following formula for each of them
X=sum(X,2/value)
What should I do?
I have tried as follows:
data want;
array my_array{0-10} $ _temporary_;
X=0;
Do i=1 to 5;
My_array(i)=sum(x,2/value)*i;
X= =sum(x,2/value)*i;
End;
Total=X;
Run;
However I am not looping through value, only through time (i goes from 1 to 4).
I would like to calculate for each time X applying the formula above, in order to have one column extra in the table above, then get the sum of these values.
In the example provided by Kermit in the answer below, the expected output (values under x should satisfy the formula mentioned above) would be the following:
time value x sum_x
3 0.03 200
6 0.04 300
9 0.05 360
12 0.06 400
Your expected results do not seem to match your explanation of the formula. You could use two arrays to allow you to pair the TIME and VALUE amounts.
data want;
array t [4] _temporary_ (3 6 9 12);
array v [4] _temporary_ (0.03 0.04 0.05 0.06);
do index=1 to dim(t);
time=t[index];
value=v[index];
x=sum(x,2/value)*index;
output;
end;
run;
Results
Obs index time value x
1 1 3 0.03 66.67
2 2 6 0.04 233.33
3 3 9 0.05 820.00
4 4 12 0.06 3413.33
If I understand correctly, time would be set on a quarterly basis and you would like to get the sum of X for each time. Next time, consider giving the expected output in your question.
data stage1;
do time=3 to 12 by 3;
do value = 0.03, 0.04, 0.05, 0.06;
x=(2/value)*time;
output;
end;
end;
run;
proc sort data=stage1;
by time value;
run;
data want;
do _n_=1 by 1 until(last.time);
set stage1;
by time;
sum_x=sum(sum_x, x);
output;
end;
run;
time value x sum_x
3 0.03 200 200
3 0.04 150 350
3 0.05 120 470
3 0.06 100 570
6 0.03 400 400
6 0.04 300 700
6 0.05 240 940
6 0.06 200 1140
9 0.03 600 600
9 0.04 450 1050
9 0.05 360 1410
9 0.06 300 1710
12 0.03 800 800
12 0.04 600 1400
12 0.05 480 1880
12 0.06 400 2280
EDIT after comments
Why would you use a do loop? Just perform element-wise multiplication within a table.
data want;
set have;
x=(2/value)*time;
retain sum_x 0;
sum_x=sum(sum_x, x);
output;
run;

How to calculate cumulative product in SAS?

I need to create a variable that takes the product of the values of all prior values and including the one in the current obs.
data temp;
input time cond_prob;
datalines;
1 1
2 0.2
3 0.3
4 0.4
5 0.6
;
run;
Final data should be:
1 1
2 0.2 (1*0.2)
3 0.06 (0.2* 0.3)
4 0.024 (0.06 * 0.4
5 0.0144 (0.024 *0.6)
This seems like a simple code but I can't get it to work. I can do cumulative sums but cumulative product is not working when using the same logic.
Use the RETAIN functionality.
For the first record I set it to a value of 1 because anything multiplied by 1 will stay the same.
data want;
set temp;
retain cum_product 1;
cum_product = cond_prob * cum_product;
run;

Unable to execute my hash table correctly/ SAS

I have a data step before the code below called "simulation_tracking3", that outputs something like:
CDFx Allowed_Claims
.06 120
.12 13
.15 1400
I want my hash table to average the Allowed_Claims based on a randomly generated value (from 0 to 1). For example, let's call this Process A, if Px = rand('Uniform',0,1) yields .09, I want it to average between the Allowed_Claims values where Px = .06 and Px = 0.12, which is (120+13)/2
The role of the array is that it dictates how many iterations of Process A I want. The array is
Members {24} _temporary_ (5 6 8 10 12 15 20 25 30 40 50 60 70 80
90 100 125 150 175 200 250 300 400 500);
So when the loop starts, it will perform 5 iterations of Process A, thereby producing 5 averaged "allowed_claims" values. I want the sum of these five claims.
Then, the loop will continue and perform 6 iterations of Process A and produce 6 averaged "allowed_claims" values. Again, I want the sum of these 6 claims.
I want the output table to look like:
`
Member[i] Average_Expected_Claims
5 (sum of 5 'averaged 'claims)
6 (sum of 6 'averaged' claims)
8 (sum of 8 'averaged' claims)
The code that I currently have is below. My errors occur here:
do rc = hi_iter.first() by 0 until (hi_iter.next()_ ne 0 or CDFx gt rand_value);
rc = hi_iter.prev();
The error says, respectively:
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &,
*, **, +, -, /, <, <=, <>, =, >, ><, >=, AND, EQ, GE, GT, IN,
LE, LT, MAX, MIN, NE, NG, NL, NOTIN, OR, ^=, |, ||, ~=.
Blockquote
ERROR: DATA STEP Component Object failure. Aborted during the
COMPILATION phase.
data simulation_members; *simulates allowed claims for each member in member array;
call streaminit(454);
array members [24] _temporary_ (5 6 8 10 12 15 20 25 30 40 50
60 70 80 90 100 125 150 175 200 250 300 400 500); *any number of members here is fine;
if _n_ eq 1 then do; * initiliaze the hash tables;
if 0 then set simulation_tracking3; * defines the variables used;
declare hash _iter(dataset:'simulation_tracking3', ordered: 'a'); *ordered = ascending - do not need a sort first;
_iter.defineKey('CDFx'); * key is artificial, but has to exist;
_iter.defineData('CDFx','Allowed_Claims'); * data variables to retrieve;
_iter.defineDone();
declare hiter hi_iter('_iter'); * the iterator object;
end;
do _i_member = 1 to dim(members); * iterate over members array;
call missing(claims_simulated);
do _i_simul = 1 to members[_i_member]-1;
rand_value = rand('Uniform',0,1);
do rc = hi_iter.first() by 0 until (hi_iter.next()_ ne 0 or CDFx gt rand_value);
end;
ac_max = allowed_claims;
rc = hi_iter.prev();
ac_min = allowed_claims;
claims_simulated + mean(ac_max,ac_min);
put rand_value= claims_simulated=; *just for logging;
end;
putlog;
output; *drop unnecessary columns;
end;
stop;
run;

Unable to understand output using leave statement

data primes;
length status $12.;
do i=1 to 4;
status='Prime';
do j=2 to i-1;
if mod(i, j) = 0 then do;
status='Composite';
leave; *exit loop;
end;
end;
output;
end;
run;
proc print data = primes;
run;
Above is the program that I ran and below is the output. I am unable to understand how the value of i when the numbers are prime. I have mentioned i should go till n-1 but in the output the value of i =n for primes. Can someone please help me understand this?
Obs status i j
1 Prime 1 2
2 Prime 2 2
3 Prime 3 3
4 Composite 4 2
If i=1 then the second loop is j=2 to 0 which means the loop never starts. The j loop never executes. You can add an explicit output or put statement to see this.

Calculating frequency of fractions in SAS

I'm trying to calculate the frequency of fractions in my data set (excluding whole numbers).
For example, my variable P takes values 24+1/2, 97+3/8, 12+1/4, 57+1/2, etc. and I'm looking to find the frequency of 1/2, 3/8, and so on. Can anyone help?!
Thanks in advance!
Clyde013
Clyde013, here is one way, assuming that p is of character type. hth. cheers, chang
> Pulled from SAS-L
/* test data -- if p is a character var */
data one;
input p $ ##;
cards;
24+1/2
97+3/8
12+1/4
57+1/2
36 3/8 ;
run;
/* frequencies of frations? */
data two;
set one;
whole = scan(p, 1, "+");
frac = scan(p, 2, "+");
run;
proc freq data=two;
tables frac;
run;
/* on lst
Cumulative Cumulative
frac Frequency Percent Frequency Percent
---------------------------------------------------------
1/2 2 50.00 2 50.00
1/4 1 25.00 3 75.00
3/8 1 25.00 4 100.00
Frequency Missing = 2 */