GKJohn
GKJohn

Reputation: 21

counter inside of a macro

this is for SAS code

my code is this:

%macro replicate (new, out, n);
data &out;
set &new;
%do i=1 %to &n-1;
data &out;
set &out &new;
if d <.22 then count +1;
run;

/* calling the macro with this line */ %replicate (new, out, 8);

here are the first few observations in the data set (called new) field names are a thru f .....(so note that d (mentioned in the loop) is the fourth value)

  1. 0.10, 0.15, 0.16, 0.22, 0.30, 1
  2. 0.07, 0.14, 0.15, 0.21, 0.29, 1
  3. 0.10, 0.15, 0.16, 0.22, 0.30, 1
  4. 0.09, 0.14, 0.15, 0.21, 0.30, 1

the corresponding values of count are 0, 7, 1, 8, .....

regarding the purpose for this code, I am teaching a stats course, and trying to ultimately show how in the long run, the counter total should work according to the laws of probability (column D numbers have been randomly generated) the numbers came from an arbitrary example.

I have no idea how that is being calculated. can anybody help?

thanks

John

Upvotes: 1

Views: 270

Answers (1)

Quentin
Quentin

Reputation: 6378

To understand what is happening, I suggest you get rid of the macro logic, and run the code that is generated by your macro call step by step, looking at the results.

Sample data:

data new;
  input d;
  cards;
0.22
0.21
0.22
0.21
;

Before the loop you have:

68   data out;
69     set new;
70     put (d)(=);
71   run;

d=0.22
d=0.21
d=0.22
d=0.21

Nothing special there. On the first iteration of the loop you introduce the counter, and it works as one would expect:

3   data out;
74     set out new;
75     if d < .22 then count+1 ;
76     put (d count)(=);
77   run;

d=0.22 count=0
d=0.21 count=1
d=0.22 count=1
d=0.21 count=2
d=0.22 count=2
d=0.21 count=3
d=0.22 count=3
d=0.21 count=4

On the second iteration of the loop note that the variable COUNT already exists in the data being read in (work.OUT on the SET statement). Therefore for those first eight records, the existing value of count is conditionally incremented by one. It is not a new counter. If you want a new counter, you could change the SET statement to set out(drop=count) new ;

So &i=2 iteration of the loop looks like:

79   data out;
80     set out new;
81     if d < .22 then count+1 ;
82     put (d count)(=);
83   run;

d=0.22 count=0
d=0.21 count=2
d=0.22 count=1
d=0.21 count=3
d=0.22 count=2
d=0.21 count=4
d=0.22 count=3
d=0.21 count=5
d=0.22 count=.
d=0.21 count=1
d=0.22 count=1
d=0.21 count=2

If you keep on resubmitting that step, on the 7th iteration you get what you state in the question:

109  data out;
110    set out new;
111    if d < .22 then count+1 ;
112    put (d count)(=);
113  run;

d=0.22 count=0
d=0.21 count=7
d=0.22 count=1
d=0.21 count=8
d=0.22 count=2
d=0.21 count=9
d=0.22 count=3
d=0.21 count=10
d=0.22 count=.
d=0.21 count=6
d=0.22 count=1
d=0.21 count=7
d=0.22 count=.
d=0.21 count=5
d=0.22 count=1
d=0.21 count=6
d=0.22 count=.
d=0.21 count=4
d=0.22 count=1
d=0.21 count=5
d=0.22 count=.
d=0.21 count=3
d=0.22 count=1
d=0.21 count=4
d=0.22 count=.
d=0.21 count=2
d=0.22 count=1
d=0.21 count=3
d=0.22 count=.
d=0.21 count=1
d=0.22 count=1
d=0.21 count=2

I'm still not clear what you are trying to do. It's an odd construction to continually overwrite work.out with itself, appending itself. But playing with the DATA step code should help show what is happening.

Upvotes: 1

Related Questions