<?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: How to assign the value of last obs to other obs in the same group? in Graphics Programming</title>
    <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573260#M18484</link>
    <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/138205"&gt;@novinosrin&lt;/a&gt;&amp;nbsp;: "Imitation is the sincerest form of flattery" ;).&lt;/P&gt;</description>
    <pubDate>Sat, 13 Jul 2019 01:42:58 GMT</pubDate>
    <dc:creator>hashman</dc:creator>
    <dc:date>2019-07-13T01:42:58Z</dc:date>
    <item>
      <title>How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573193#M18478</link>
      <description>&lt;P&gt;Suppose I have a dataset:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;--Table 1--     
ID  Amount    
A   0.1            
A   0.2        
A   0.3         
B   0.4        
B   0.5  &lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I used retain to create a new variable of total amount of each ID&lt;/P&gt;&lt;P&gt;:&lt;/P&gt;&lt;PRE&gt;data sample;
   set sample;
   by ID amout;
   if first.ID then Total_amount = 0;
   Total_amount = Total_amount +amount;
run;&lt;/PRE&gt;&lt;P&gt;And this will be the output dataset:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;--Table 2--     
ID  Amount Total_amount     
A   0.1        0.1    
A   0.2        0.3
&lt;STRONG&gt;A   0.3        0.6&lt;/STRONG&gt;
B   0.4        0.4
&lt;STRONG&gt;B   0.5        0.9&lt;/STRONG&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;But now I want to assign the true total_amout to each obs. The output I want is:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;--Table 2--     
ID  Amount Total_amount     
A   0.1        0.6    
A   0.2        0.6
&lt;STRONG&gt;A   0.3        0.6&lt;/STRONG&gt;
B   0.4        0.9
&lt;STRONG&gt;B   0.5        0.9&lt;/STRONG&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;Is there anyway to achieve it? Now I try to sort the data in descending order and than retain the total_amount.&lt;/P&gt;&lt;PRE&gt;data sample;
   set sample;
   by ID descending amout;
   if first.ID then Total_amount_1 = Total_amount;
run;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;--Table 2--     
ID  Amount Total_amount Total_amount_1    
&lt;STRONG&gt;A   0.3        0.6  &lt;/STRONG&gt;       0.6
A   0.2        0.3         0.6
A   0.1        0.1         0.6
&lt;STRONG&gt;B   0.5        0.9         0.9&lt;/STRONG&gt;
B   0.4        0.4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.9&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;Although I can get what I want by this way, I think this method is kind of stupid. I hope there are some better methods.&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2019 19:34:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573193#M18478</guid>
      <dc:creator>Ada77</dc:creator>
      <dc:date>2019-07-12T19:34:50Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573196#M18479</link>
      <description>&lt;P&gt;If you don't really want/ need the cumulative total here is one way.&lt;/P&gt;
&lt;PRE&gt;data have;
input ID $  Amount    ;
datalines;
A   0.1            
A   0.2        
A   0.3         
B   0.4        
B   0.5 
;

proc sql;
   create table want as
   select a.*, b.total 
   from have as a
        left join
        (select id, sum(amount) as total
         from have
         group by id) as b
     on a.id = b.id
 ;
quit; &lt;/PRE&gt;
&lt;P&gt;basic approach get the sum then merge back to the original data.&lt;/P&gt;
&lt;P&gt;Lots of posts on the forum about this topic.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;BTW, be careful of using the&lt;/P&gt;
&lt;P&gt;Data setname;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set setname;&lt;/P&gt;
&lt;P&gt;construct. This replaces your existing data set and a logic error could change values that you don't want and will require going back to recover the original values.&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2019 19:44:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573196#M18479</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2019-07-12T19:44:06Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573197#M18480</link>
      <description>&lt;P&gt;This "automatic remerging" can easily be achieved in SQL:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql;
create table want as
select
  id,
  amount,
  sum(amount) as total_amount
from have
group by id;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2019 19:42:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573197#M18480</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2019-07-12T19:42:39Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573216#M18481</link>
      <description>&lt;P&gt;Thank you so much!&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2019 20:36:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573216#M18481</guid>
      <dc:creator>Ada77</dc:creator>
      <dc:date>2019-07-12T20:36:45Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573217#M18482</link>
      <description>Thank you so much, it really helps&lt;BR /&gt;</description>
      <pubDate>Fri, 12 Jul 2019 20:37:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573217#M18482</guid>
      <dc:creator>Ada77</dc:creator>
      <dc:date>2019-07-12T20:37:14Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573218#M18483</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/257597"&gt;@Ada77&lt;/a&gt;&amp;nbsp; &amp;nbsp;Try this&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;



data have;
input ID $  Amount   ;
cards;
A   0.1 
A   0.2        
A   0.3         
B   0.4        
B   0.5 
;
 
data want;
if _n_=1 then do;
 dcl hash H (ordered: "d") ;
   h.definekey  ("id","Total_amount") ;
   h.definedata ("amount","Total_amount") ;
   h.definedone () ;
   dcl hiter hi('h');
  end;
do until(last.id);
set have;
by id;
Total_amount =sum(Total_amount ,amount);
rc=h.add();
end;
Total_amount1=Total_amount;
do while(hi.next()=0);
output;
end;
h.clear();
drop rc;
run;


&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/21262"&gt;@hashman&lt;/a&gt;&amp;nbsp; &amp;nbsp;Guru, I plagiarized your solution that you taught me yesterday. I admit it before you notice it. Rather, I consider that as I am a good student who pays attention in the affirmative. I am not apologizing unless you demand one. &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2019 20:46:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573218#M18483</guid>
      <dc:creator>novinosrin</dc:creator>
      <dc:date>2019-07-12T20:46:11Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573260#M18484</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/138205"&gt;@novinosrin&lt;/a&gt;&amp;nbsp;: "Imitation is the sincerest form of flattery" ;).&lt;/P&gt;</description>
      <pubDate>Sat, 13 Jul 2019 01:42:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573260#M18484</guid>
      <dc:creator>hashman</dc:creator>
      <dc:date>2019-07-13T01:42:58Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573298#M18485</link>
      <description>&lt;P&gt;The simplest is to use the automatic re-merge feature of PROC SQL.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;create table want as select *,sum(amount) as total from sample group by id;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;But if you really need to use a data step for some other reason then consider using a double-DOW loop.&amp;nbsp; The first to calculate the total for the group and the second to output the detail rows.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
do until (last.id);
  set sample;
  by id;
  total=sum(total,amount);
end;
do until (last.id);
  set sample;
  by id;
  output;
end;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 13 Jul 2019 15:31:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573298#M18485</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2019-07-13T15:31:27Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573317#M18486</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;: Replying to your post, as you've included both the double DoW and SQL, but also to&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt;,&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13884"&gt;@ballardw&lt;/a&gt;,&amp;nbsp;and &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/138205"&gt;@novinosrin&lt;/a&gt;&amp;nbsp;(and of course to the OP and/or anyone else watching the thread).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;1.&amp;nbsp;If the input data set is &lt;EM&gt;not sorted&lt;/EM&gt;, it's more efficient to use the hash object to get the group totals and attach them back to the original records in the same step - since this approach avoids sorting altogether (keeping the records in the original order):&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want ;                             
  if _n_ = 1 then do ;                  
    dcl hash h () ;           
    h.definekey ("id") ;                
    h.definedata ("sum") ;              
    h.definedone () ;                   
    do until (z) ;                      
      set have (keep = id amt) end = z ;
      if h.find() ne 0 then sum = amt ; 
      else                  sum + amt ; 
      h.replace() ;                     
    end ;                               
  end ;                                 
  set have ;                            
  h.find() ;                            
run ;                                   
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;2. If the input data set is sorted by ID, the double DoW is most efficient - &lt;STRONG&gt;&lt;EM&gt;provided&lt;/EM&gt; &lt;/STRONG&gt;that certain performance-promoting considerations (in &lt;STRONG&gt;&lt;EM&gt;bold italics&lt;/EM&gt;&lt;/STRONG&gt; below) are observed;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want (drop = amt) ;           
  do &lt;STRONG&gt;&lt;EM&gt;_n_ = 1 by 1&lt;/EM&gt;&lt;/STRONG&gt; until (last.id) ;
    set have (&lt;STRONG&gt;&lt;EM&gt;keep = id amt&lt;/EM&gt;&lt;/STRONG&gt;) ;     
    by id ;                        
    sum = sum (sum, amt) ;         
  end ;                            
  do &lt;STRONG&gt;&lt;EM&gt;_n_ = 1 to _n_&lt;/EM&gt;&lt;/STRONG&gt; ;              
    set have ;    &lt;BR /&gt;   &lt;EM&gt;/&lt;STRONG&gt;* note: no BY statement here */&lt;/STRONG&gt; &lt;/EM&gt;                
    output ;                       
  end ;                            
run ;                              
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The KEEP option on the first SET is obvious - there's no need to read any variables but ID and AMT on the first pass. The counting instead of the second BY is less obvious since most folks tend to think that BY doesn't exact any performance penalty. Yet it does since it makes the DATA step do extra work comparing the values of the BY variables in the PDV with those in the buffer to set FIRST.x and LAST.x as many times as there are BY groups in the input times the number of BY variables.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Because the program above explicitly relies on the order by ID, it works the same way irrespective of whether the input data set contains the SORTEDBY=ID data set flag set by proc SORT or is merely ordered intrinsically and doesn't have the flag set.&amp;nbsp;But not so with SQL! This is because if the optimizer doesn't see SORTEDBY=ID in the header of the input data set, it will choose the path requiring sorting (indicated by the SQXSRT access method if the system option MSGLEVEL=I and SQL statement option _METHOD are in effect). Which is why, as a &lt;STRONG&gt;&lt;EM&gt;precaution&lt;/EM&gt;&lt;/STRONG&gt;, it's always a good idea to tell SQL that input is sorted (if it is indeed ordered, of course): If the flag is already set by SORT, it won't hurt; but if it is not, the unnecessary sorting will be avoided:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql _method stimer ;                                                           
  create table want as select *, sum (amt) as sum from have (&lt;EM&gt;&lt;STRONG&gt;sortedby=id&lt;/STRONG&gt;&lt;/EM&gt;) group id ;
quit ;                                                                              
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;In this case, the underlying algorithm is essentially the same as with the double DoW above, though for whatever reason the latter still runs ~40% faster.&amp;nbsp; &amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Kind regards&lt;/P&gt;
&lt;P&gt;Paul D.&amp;nbsp; &amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 13 Jul 2019 21:14:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573317#M18486</guid>
      <dc:creator>hashman</dc:creator>
      <dc:date>2019-07-13T21:14:50Z</dc:date>
    </item>
    <item>
      <title>Re: How to assign the value of last obs to other obs in the same group?</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573487#M18489</link>
      <description>&lt;P&gt;Here's a slightly different version, how I would do it:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;data sample;&lt;BR /&gt;input ID $1 Amount; &lt;BR /&gt;datalines; &lt;BR /&gt;A 0.1 &lt;BR /&gt;A 0.2 &lt;BR /&gt;A 0.3 &lt;BR /&gt;B 0.4 &lt;BR /&gt;B 0.5 &lt;BR /&gt;;&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;proc sql noprint;&lt;BR /&gt;create table sample as&lt;BR /&gt;select unique *, sum(amount) as total_amount&lt;BR /&gt;from sample&lt;BR /&gt;group by id;&lt;BR /&gt;quit; run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 15 Jul 2019 13:22:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/How-to-assign-the-value-of-last-obs-to-other-obs-in-the-same/m-p/573487#M18489</guid>
      <dc:creator>GraphGuy</dc:creator>
      <dc:date>2019-07-15T13:22:16Z</dc:date>
    </item>
  </channel>
</rss>

