<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Iterative Loop in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649409#M194689</link>
    <description>&lt;P&gt;Hi Ballardw...thank you for your response and the suggestion.....I will make the corrections to deal with the&amp;nbsp;"if not first.counts1"&amp;nbsp;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The "12" was chosen since that was the number of iterations necessary for all the variables/fields to populate since many of them depends on the previous record values.&lt;/P&gt;</description>
    <pubDate>Wed, 20 May 2020 23:53:40 GMT</pubDate>
    <dc:creator>twildone</dc:creator>
    <dc:date>2020-05-20T23:53:40Z</dc:date>
    <item>
      <title>Iterative Loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649333#M194646</link>
      <description>&lt;P&gt;Hi....I am trying to create the output that I was able to produce in the output table Want. I was only able to do so by creating a macro and arbitrary selecting "12" in the "%do I=1 %to 12;" statement. This seems to work as long as the number of iterations needed for each ID groups is no more than 12. My problem is that I don't know in advance how many iterations are actually needed and would like it to iterated as long as BegAmount1 is not missing for each ID group. Thanks.&lt;/P&gt;
&lt;PRE&gt;data have;
    format ID Counts Counts1 ShowAmount NumberDays NumberDaysMonth NumberDaysBeg NumberDaysEnd BegAmount best12.;
    infile datalines4 dlm='7F'x missover dsd;
    input ID Counts Counts1 ShowAmount NumberDays NumberDaysMonth NumberDaysBeg NumberDaysEnd BegAmount : best32.;
datalines4;
152 &amp;#127;1&amp;#127; 1 &amp;#127;.&amp;#127; 36 &amp;#127;28 &amp;#127;0 &amp;#127;28 &amp;#127;3650
152&amp;#127; 1&amp;#127; 2&amp;#127; .&amp;#127; 36 &amp;#127;8&amp;#127; 0&amp;#127; 8 &amp;#127;3650
152&amp;#127; 2&amp;#127; 3 &amp;#127;.&amp;#127; 85&amp;#127; 14&amp;#127; 0 &amp;#127;14 &amp;#127;4100
152 &amp;#127;2&amp;#127; 4&amp;#127; .&amp;#127; 85&amp;#127; 31 &amp;#127;0&amp;#127; 31&amp;#127; 4100
152 &amp;#127;2&amp;#127; 5&amp;#127; 700&amp;#127; 85 &amp;#127;30 &amp;#127;10&amp;#127; 20&amp;#127; 4100
152 &amp;#127;2&amp;#127; 6 &amp;#127;.&amp;#127; 85&amp;#127; 10 &amp;#127;0&amp;#127; 10 &amp;#127;4100
152 &amp;#127;3 &amp;#127;7 &amp;#127;.&amp;#127; 71 &amp;#127;19&amp;#127; 0&amp;#127; 19 &amp;#127;4650
152&amp;#127; 3 &amp;#127;8&amp;#127; 450 &amp;#127;71&amp;#127; 29&amp;#127; 28&amp;#127; 1 &amp;#127;4650
152&amp;#127; 3&amp;#127; 9&amp;#127; .&amp;#127; 71 &amp;#127;23&amp;#127; 0 &amp;#127;23&amp;#127; 4650
152&amp;#127; 4 &amp;#127;10&amp;#127; .&amp;#127; 85&amp;#127; 25 &amp;#127;0&amp;#127; 25 &amp;#127;4650
152&amp;#127; 4&amp;#127; 11 &amp;#127;.&amp;#127; 85&amp;#127; 36 &amp;#127;0&amp;#127; 31&amp;#127; 4650
152 &amp;#127;4&amp;#127; 12&amp;#127; .&amp;#127; 85&amp;#127; 29&amp;#127; 0 &amp;#127;29&amp;#127; 4650
154 &amp;#127;1&amp;#127; 1 &amp;#127;.&amp;#127; 36 &amp;#127;28&amp;#127; 0&amp;#127; 28&amp;#127; 3650
154&amp;#127; 1&amp;#127; 2&amp;#127; .&amp;#127; 36 &amp;#127;8&amp;#127; 0&amp;#127; 8 &amp;#127;3650
154&amp;#127; 2&amp;#127; 3 &amp;#127;.&amp;#127; 85 &amp;#127;14 &amp;#127;0 &amp;#127;14 &amp;#127;4100
154&amp;#127; 2&amp;#127; 4&amp;#127; .&amp;#127; 85 &amp;#127;31 &amp;#127;0&amp;#127; 31&amp;#127; 4100
154 &amp;#127;2 &amp;#127;5 &amp;#127;700 &amp;#127;85&amp;#127; 30&amp;#127; 10 &amp;#127;20&amp;#127; 4100
155&amp;#127; 2&amp;#127; 1 &amp;#127;.&amp;#127; 85 &amp;#127;10 &amp;#127;0 &amp;#127;10&amp;#127; 4100
155&amp;#127; 3&amp;#127; 2&amp;#127; . &amp;#127;71 &amp;#127;19&amp;#127; 0&amp;#127; 19 &amp;#127;4650
155&amp;#127; 3 &amp;#127;3 &amp;#127;450&amp;#127; 71 &amp;#127;29&amp;#127; 28&amp;#127; 1&amp;#127; 4650
155 &amp;#127;3&amp;#127; 4&amp;#127; .&amp;#127; 71&amp;#127; 23&amp;#127; 0&amp;#127; 23 &amp;#127;4650
155&amp;#127; 4&amp;#127; 5&amp;#127; .&amp;#127; 85 &amp;#127;25&amp;#127; 0&amp;#127; 25&amp;#127; 4650
155&amp;#127; 4&amp;#127; 6 &amp;#127;.&amp;#127; 85 &amp;#127;36 &amp;#127;0&amp;#127; 31&amp;#127; 4650
155&amp;#127; 4 &amp;#127;7 &amp;#127;.&amp;#127; 85 &amp;#127;29 &amp;#127;0&amp;#127; 29&amp;#127; 4650
;;;;

data have;
	set have;
		if ShowAmount = .
			then ShowAmount = 0;
run;

data have(drop=NumberDaysMonth2 NumberDays2);
	set have;
	by ID Counts Counts1 notsorted;
		NumberDaysMonth2 = lag(NumberDaysMonth);
		NumberDays2 = lag(NumberDays1);
		NumberDays1 = NumberDays2 - NumberDaysMonth2;
		if Counts ^=lag(Counts) then 
			NumberDays1 = NumberDays;
run;

data want2;
format BegAmount BegAmount1 EndAmount MonthlyAmount EndAmount1 ShowAmount bestx12.2;
	set have;
	by ID Counts Counts1 notsorted;
		if first.ID and first.Counts and first.Counts1 then do;
			BegAmount1 = BegAmount;
			EndAmount = (BegAmount + ShowAmount);	
			NumberDays1 = NumberDays1;
			MonthlyAmount = (((NumberDaysBeg/NumberDays1)*BegAmount1) + ((NumberDaysEnd/NumberDays1)*EndAmount));
            EndAmount1 = (EndAmount - MonthlyAmount); 
		end;
run;

data want1;
format BegAmount EndAmount2 BegAmount2 ShowAmount bestx12.2;
	set want2;
	by ID notsorted;
		if not first.Counts1 then 
			EndAmount2 = lag(EndAmount1);
			else EndAmount2 = EndAmount2;
		if not first.Counts1 then 
			BegAmount2 = lag(BegAmount);
			else BegAmount2 = BegAmount2;
		if not first.Counts1 then 
			NumberDays2 = lag(NumberDays1);
			else NumberDays2 = NumberDays2;
		if not first.Counts1 then 
			NumberDaysMonth2 = lag(NumberDaysMonth);
			else NumberDaysMonth2 = NumberDaysMonth2;
		if not first.Counts1 then 
			Counts2 = lag(Counts);
			else Counts2 = Counts;
		if missing(BegAmount1) then
			BegAmount1 = BegAmount - BegAmount2 + EndAmount2;
			else BegAmount1 = BegAmount1;
		if missing(EndAmount) then 
			EndAmount = BegAmount - BegAmount2 + ShowAmount + EndAmount2;
			else EndAmount = EndAmount;
		if missing(NumberDays1) and Counts = Counts2 then 
			NumberDays1 = NumberDays2 - NumberDaysMonth2;
			else NumberDays1 = NumberDays1;
		if missing(	MonthlyAmount) then 
			MonthlyAmount = (((NumberDaysBeg/NumberDays1)*BegAmount1) + ((NumberDaysEnd/NumberDays1)*EndAmount));
			else MonthlyAmount = MonthlyAmount;
		if missing(EndAmount1) then
            EndAmount1 = (EndAmount - MonthlyAmount);
		else EndAmount1 = EndAmount1;
		output;
run;

%macro test();
%do i=1 %to 12;
data want1;
format BegAmount BegAmount1 EndAmount MonthlyAmount EndAmount1 EndAmount2 BegAmount2 ShowAmount bestx12.2;
	set want1;
	by ID notsorted;
		if not first.Counts1 then 
			EndAmount2 = lag(EndAmount1);
			else EndAmount2 = EndAmount2;
		if not first.Counts1 then 
			BegAmount2 = lag(BegAmount);
			else BegAmount2 = BegAmount2;
		if not first.Counts1 then 
			NumberDays2 = lag(NumberDays1);
			else NumberDays2 = NumberDays2;
		if not first.Counts1 then 
			NumberDaysMonth2 = lag(NumberDaysMonth);
			else NumberDaysMonth2 = NumberDaysMonth2;
		if not first.Counts1 then 
			Counts2 = lag(Counts);
			else Counts2 = Counts2;
		if missing(BegAmount1) then
			BegAmount1 = BegAmount - BegAmount2 + EndAmount2;
			else BegAmount1 = BegAmount1;
		if missing(EndAmount) then 
			EndAmount = BegAmount - BegAmount2 + ShowAmount + EndAmount2;
			else EndAmount = EndAmount;
		if missing(NumberDays1) and Counts = Counts2 then 
			NumberDays1 = NumberDays2 - NumberDaysMonth2;
			else NumberDays1 = NumberDays1;
		if missing(	MonthlyAmount) then 
			MonthlyAmount = (((NumberDaysBeg/NumberDays1)*BegAmount1) + ((NumberDaysEnd/NumberDays1)*EndAmount));
			else MonthlyAmount = MonthlyAmount;
		if missing(EndAmount1) then
            EndAmount1 = (EndAmount - MonthlyAmount);
		else EndAmount1 = EndAmount1;
		output;
run;
%end;

%mend test;
%test


data want(drop=BegAmount2 EndAmount2 NumberDays2 NumberDaysMonth2 Counts2 NumberDays1 EndAmount1 BegAmount);
retain ID Counts Counts1 NumberDays NumberDaysMonth NumberDaysBeg NumberDaysEnd ShowAmount BegAmount1 MonthlyAmount EndAmount;
	set want1;
run;

data want;
	set want;
	rename BegAmount1 = BegAmount;
run;
&lt;/PRE&gt;</description>
      <pubDate>Wed, 20 May 2020 18:48:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649333#M194646</guid>
      <dc:creator>twildone</dc:creator>
      <dc:date>2020-05-20T18:48:25Z</dc:date>
    </item>
    <item>
      <title>Re: Iterative Loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649382#M194670</link>
      <description>&lt;P&gt;I don't know what you expect. Since your Want1 uses many instances of "If not first.counts1" and you do not have Counts1 on the by statement the First is always undefined (missing) and and so 'not first.counts1' is &lt;STRONG&gt;always&lt;/STRONG&gt; true. So any result is very suspect as to the output matching you desire.&lt;/P&gt;
&lt;P&gt;Consider:&lt;/P&gt;
&lt;PRE&gt;proc sort data=sashelp.class out=work.class;
   by sex;
run;

data example;
   set work.class;
   by sex;
   if not first.age then newname=lag(name);
run;

/* is exactly the same as*/
data example2;
  set work.class;
  newname=lag(name);
run;&lt;/PRE&gt;
&lt;P&gt;I have to guess since you chose 12 loops that you may be doing something based on months of a year. If so say so. I have a suspicion that you really need something like a start date, an end date and the rules of what you are doing. Intnx and Intck likely get you any of the intermediate periods you may need. But again, an actual rule or two would help.&lt;/P&gt;
&lt;P&gt;And what are you trying to do. 'match an example' is fraught with peril as without an idea of what is supposed to happen it is hard to generalize to a rule (i.e. code)&lt;/P&gt;</description>
      <pubDate>Wed, 20 May 2020 20:35:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649382#M194670</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2020-05-20T20:35:50Z</dc:date>
    </item>
    <item>
      <title>Re: Iterative Loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649385#M194671</link>
      <description>&lt;P&gt;Did you use 12 because it is the max number of observations of&amp;nbsp; IDs ?&lt;/P&gt;
&lt;P&gt;If positive, you can count it and assign it in a macro variable:&lt;/P&gt;
&lt;P&gt;In first step:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
    format ID Counts Counts1 ShowAmount NumberDays NumberDaysMonth 
               NumberDaysBeg NumberDaysEnd BegAmount best12.;
   retain count_iter  max_iter  saved_id 0;
   drop  count_iter  max_iter  saved_id ;
    infile datalines4 dlm='7F'x missover dsd end=eof;
    input ID Counts Counts1 ShowAmount NumberDays NumberDaysMonth 
             NumberDaysBeg NumberDaysEnd BegAmount : best32.;
  
    if  ID ne saved_ID then do;
        max_iter = max(max_iter, count_iter);
        count_iter=0;
    end;
    count_iter +1;    
    if eof then call symput('max_iter' , strip(max_iter));
datalines4;
   ....&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;then use the macro variable instead the constant 12:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro test();
%do i=1 %to &amp;amp;max_iter;
  ....&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;beyond, I'm not sure that your code works as you expect, because of using LAG function under conditions.&lt;/P&gt;</description>
      <pubDate>Wed, 20 May 2020 20:58:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649385#M194671</guid>
      <dc:creator>Shmuel</dc:creator>
      <dc:date>2020-05-20T20:58:24Z</dc:date>
    </item>
    <item>
      <title>Re: Iterative Loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649405#M194687</link>
      <description>&lt;P&gt;Hi Shmuel...thanks for your response. Yes you are correct. I selected 12 because it was the maximum number&amp;nbsp;of records when the records are grouped by&amp;nbsp;ID's and it would result in all the required fields to be populated after the completion of the number of iterations. &amp;nbsp;I guess I can always select a large enough number to ensure the number of iterations necessary are performed but not too sure how efficient that would be.&lt;/P&gt;</description>
      <pubDate>Wed, 20 May 2020 23:46:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649405#M194687</guid>
      <dc:creator>twildone</dc:creator>
      <dc:date>2020-05-20T23:46:05Z</dc:date>
    </item>
    <item>
      <title>Re: Iterative Loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649409#M194689</link>
      <description>&lt;P&gt;Hi Ballardw...thank you for your response and the suggestion.....I will make the corrections to deal with the&amp;nbsp;"if not first.counts1"&amp;nbsp;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The "12" was chosen since that was the number of iterations necessary for all the variables/fields to populate since many of them depends on the previous record values.&lt;/P&gt;</description>
      <pubDate>Wed, 20 May 2020 23:53:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649409#M194689</guid>
      <dc:creator>twildone</dc:creator>
      <dc:date>2020-05-20T23:53:40Z</dc:date>
    </item>
    <item>
      <title>Re: Iterative Loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649419#M194693</link>
      <description>&lt;P&gt;And still haven't described what this is actually supposed to accomplish.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Often seeing that many variables named "numberdays" or similar tells me that likely DATES should be involved somewhere, at least in a description. And the functions INTCK which will return values like "number of days between two dates" maybe should be in the running for consideration.&lt;/P&gt;</description>
      <pubDate>Thu, 21 May 2020 00:39:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649419#M194693</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2020-05-21T00:39:51Z</dc:date>
    </item>
    <item>
      <title>Re: Iterative Loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649430#M194702</link>
      <description>&lt;P&gt;Hi....what is actually supposed to be accomplished is to obtain the MonthlyAmount which is the amount of revenue received for a project that is allocated to each month. The allocation is based on the revenue that has been received to date and the work must&amp;nbsp;that has be done, that is revenue is only recognized if the revenue has been received and work that has been completed. Since projects can take several months and revenue can be received before the start of the project or during the completion of the project, I need to pay attention to the number of days in each month that the&amp;nbsp;project was being worked on as this is used to calculate the proportion of the revenue that has been received for that particular month. The&amp;nbsp;Beginning&amp;nbsp;Amount and End Amount for each month is crucial in the calculation of the Monthly Amount. Since revenue can be received during&amp;nbsp;the completion of the project, the iterate loop is why I thought it is necessary to add the new revenue received in the month it was received and adjust the&amp;nbsp;Month's Begining Amount and End Amount.&amp;nbsp;I hope this is helpful....thanks.&lt;/P&gt;</description>
      <pubDate>Thu, 21 May 2020 01:41:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/649430#M194702</guid>
      <dc:creator>twildone</dc:creator>
      <dc:date>2020-05-21T01:41:18Z</dc:date>
    </item>
    <item>
      <title>Re: Iterative Loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/651203#M195355</link>
      <description>&lt;P&gt;Hi Shmuel....thanks for your help and suggestion.....I wasn't able to get the suggestion of creating max_iter in the data have but ended of creating a dataset of the number of rows for each ID and then taking the maximum number from all ID's and then assigned it to a macro variable. I also ended up defining all of the lag variable first before calling them. Nevertheless, it seems to work.....thanks once again.&lt;/P&gt;</description>
      <pubDate>Wed, 27 May 2020 20:01:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Iterative-Loop/m-p/651203#M195355</guid>
      <dc:creator>twildone</dc:creator>
      <dc:date>2020-05-27T20:01:10Z</dc:date>
    </item>
  </channel>
</rss>

