Your code needs further tweak. Your output stops before hitting 500.
No tweeking needed as far as total sum.
This is the output for table have:
Obs family Member Category Amount
1 A. 1 Bio 100
2 A. 1 Tab 50
3 A. 2 Che 75
4 A. 2 Bio 100
5 A. 2 Lei 50
6 A. 3 Pas 125 - total sum -> 500
7 B. 1 Bio 100
8 B. 1 Tab 50
9 B. 2 Che 75
10 B. 2 Bio 100
11 B. 2 Lei 50
12 B. 3 Pas 125 - total sum-> 500
You may have been looking at the code line:
if zAmt < zMax then output;
and thought that the output stops at < 500. Suppose zAmt (before truncating amount) is exactly 500.
Then that particular row will be outputted with the variable zStop becoming = 1. So the next record, even if amount = 1, will not be outputted.
I assume that amount > 0 for all records.
My point is to stop the outputting once the total sum >= 500.
Now, if some records have amount=0 and to be outputted after total sum >= 500, then one goes from
if zAmt < zMax then output;
to
if ((zAmt < zMax) and (zStop=0)) or (amount=0) then output;
and instead of:
zMax=500;
zStop=0;
one changes to:
zMax=500;
retain zStop;
In fact the last change needs to be made for any case. I did not see the error until I added another record for family A in the input.
Hmmm. Not sure what is happening, when I copy-paste your code and use the data in 's post, I got this log and output:
23 data have;
24 input family $ Member $ Category $ Amount ;
25 cards;
NOTE: The data set WORK.HAVE has 14 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
40 ;
41 run;
42
43 data want(keep=family member category amount);
44 array aCnt(5) $ ('Bio','Che','Tab','Pas','Lei');
45 array bCnt(5) (2,2,2,3,4);
46 array cCnt(5) ;
47 length zAmt zStop 8.;
48 zMax=500;
49 set have;
50 by family;
51
52 if first.family then do; zAmt=0; zStop=0; call missing(of cCnt(*)); end;
53 do i = 1 to dim(aCnt);
54 if Category = aCnt(i) then do;
55 cCnt(i)+1;
56 if cCnt(i) <= bCnt(i) then do;
57 zAmt+Amount;
58 if zAmt < zMax then output;
59 else do;
60 if zStop=0 then do;
61 zStop=1;
62 Amount = zMax -(zAmt-Amount);
63 output;
64 end;
2 The SAS System 18:49 Friday, January 23, 2015
65 end;
66 end;
67 end;
68 end;
69 run;
NOTE: There were 14 observations read from the data set WORK.HAVE.
NOTE: The data set WORK.WANT has 10 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.16 seconds
cpu time 0.01 seconds
70
71 proc print;run;
NOTE: There were 10 observations read from the data set WORK.WANT.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.63 seconds
cpu time 0.00 seconds
1 | A. | 1. | Bio | 100 |
2 | A. | 1. | Tab | 50 |
3 | A. | 2. | Che | 75 |
4 | A. | 2. | Bio | 100 |
5 | A. | 2. | Lei | 50 |
6 | B. | 1. | Bio | 100 |
7 | B. | 1. | Tab | 50 |
8 | B. | 2. | Che | 75 |
9 | B. | 2. | Bio | 100 |
10 | B. | 2. | Lei | 50 |
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.