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 |
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
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.