<?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: Mimic SQL Window Function in Data Step (MAX, AVG) in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/602436#M174437</link>
    <description>&lt;P&gt;You probably want to use CASE so you decide what values are fed to the aggregate function.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;CREATE TABLE WANT AS
SELECT JOBTYPE
     , AVG(case when (EDUCATION = "High_School") then SALARY else . end) as AVG_SALARY
FROM HAVE
GROUP BY JOBTYPE&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Thu, 07 Nov 2019 15:34:56 GMT</pubDate>
    <dc:creator>Tom</dc:creator>
    <dc:date>2019-11-07T15:34:56Z</dc:date>
    <item>
      <title>Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601705#M174082</link>
      <description>&lt;P&gt;Is there a way to mimic a Postgre SQL Window Function&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For example&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;DATSET&lt;/P&gt;&lt;P&gt;JobType&amp;nbsp; &amp;nbsp; &amp;nbsp;Salary&lt;/P&gt;&lt;P&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$50k&lt;/P&gt;&lt;P&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$10k&lt;/P&gt;&lt;P&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$100k&lt;/P&gt;&lt;P&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$300k&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Select JOBTYPE, SALARY, MAX(SALARY) over (PARTITION BY JOBTYPE)&amp;nbsp; AS MAXSALARY,&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AVG(SALARY) over (PARTITION BY JOBTYPE)&amp;nbsp; AS AVGSALARY&lt;/P&gt;&lt;P&gt;FROM DATASET;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;NEW DATASET&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;JobType&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Salary&amp;nbsp; &amp;nbsp; &amp;nbsp;MAXSALARY&amp;nbsp; &amp;nbsp; AVGSALARY&lt;/P&gt;&lt;P&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;$50k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$50k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $30k&lt;/P&gt;&lt;P&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$10k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $50k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$30k&lt;/P&gt;&lt;P&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$100k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$300k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$200k&lt;/P&gt;&lt;P&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $300k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$300k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;$200k&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I was thinking perhaps there was a way to sort by jobtype and then run a data step with a BY JOBTYPE statement;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you for the help.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 05 Nov 2019 16:48:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601705#M174082</guid>
      <dc:creator>whs278</dc:creator>
      <dc:date>2019-11-05T16:48:23Z</dc:date>
    </item>
    <item>
      <title>Re: Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601710#M174084</link>
      <description>&lt;P&gt;SAS does that almost automatically, no window function needed.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql;
create table want as
select *, max(salary) as maxSalary, mean(salary) as meanSalary
from have
group by JobType;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/279633"&gt;@whs278&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;Is there a way to mimic a Postgre SQL Window Function&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For example&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;DATSET&lt;/P&gt;
&lt;P&gt;JobType&amp;nbsp; &amp;nbsp; &amp;nbsp;Salary&lt;/P&gt;
&lt;P&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$50k&lt;/P&gt;
&lt;P&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$10k&lt;/P&gt;
&lt;P&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$100k&lt;/P&gt;
&lt;P&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$300k&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Select JOBTYPE, SALARY, MAX(SALARY) over (PARTITION BY JOBTYPE)&amp;nbsp; AS MAXSALARY,&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AVG(SALARY) over (PARTITION BY JOBTYPE)&amp;nbsp; AS AVGSALARY&lt;/P&gt;
&lt;P&gt;FROM DATASET;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;NEW DATASET&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;JobType&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Salary&amp;nbsp; &amp;nbsp; &amp;nbsp;MAXSALARY&amp;nbsp; &amp;nbsp; AVGSALARY&lt;/P&gt;
&lt;P&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;$50k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$50k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $30k&lt;/P&gt;
&lt;P&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$10k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $50k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$30k&lt;/P&gt;
&lt;P&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$100k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$300k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$200k&lt;/P&gt;
&lt;P&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $300k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$300k&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;$200k&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I was thinking perhaps there was a way to sort by jobtype and then run a data step with a BY JOBTYPE statement;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thank you for the help.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 05 Nov 2019 17:05:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601710#M174084</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2019-11-05T17:05:51Z</dc:date>
    </item>
    <item>
      <title>Re: Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601808#M174121</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/279633"&gt;@whs278&lt;/a&gt;: What &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13879"&gt;@Reeza&lt;/a&gt;&amp;nbsp;said.&lt;/P&gt;
&lt;P&gt;However, the answer to the question whether it can be mimicked using the DATA step, the answer is "yes", provided that one is willing to (or can) do a modicum of procedural programming (as opposed to logical set programming done via SQL). Using the hash object, it is also possible to construct a step that does the job without relying on a sorted key order - just like SQL doesn't, either.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;However, programming provisions must be made to account for the missing values of analytical variables (in your case, salary) properly, in order to prevent the averages from being corrupted. Note that below, &amp;nbsp;I've added a few extra records with missing values of salary to the sample data to test the null handling. It is done by skipping missing salary records on the aggregation (i.e. first) pass through the data using the WHERE clause. On the second pass, when the accumulated stats are merged back to the original data, this clause is skipped.&lt;/P&gt;
&lt;PRE&gt;data have ;                                                                                                                             
  input jobtype $ salary :dollar. ;                                                                                                     
  cards ;                                                                                                                               
Farmer   $50,000                                                                                                                        
Farmer   $10,000                                                                                                                        
Banker  $100,000                                                                                                                        
Banker  $300,000                                                                                                                        
&lt;FONT color="#800000"&gt;Idler          .                                                                                                                        
Idler          . &lt;/FONT&gt;                                                                                                                       
Clerk    $40,000                                                                                                                        
&lt;FONT color="#800000"&gt;Clerk          .&lt;/FONT&gt;                                                                                                                        
;                                                                                                                                       
run ;                                                                                                                                   
                                                                                                                                        
data want (drop = sum N) ;                                                                                                              
  if _n_ = 1 then do ;                                                                                                                  
    dcl hash h () ;                                                                                                                     
    h.definekey ("jobtype") ;                                                                                                           
    h.definedata ("maxsalary", "sum", "N") ;                                                                                            
    h.definedone () ;                                                                                                                   
    do until (z) ;                                                                                                                      
      set have (&lt;FONT color="#0000FF"&gt;where=(N(salary))&lt;/FONT&gt;) end = z ;                                                                                         
      if h.find() ne 0 then call missing (maxsalary, sum, N) ;                                                                          
      sum  = sum (sum, salary) ;                                                                                                        
      N    = sum (N, N (salary)) ;                                                                                                      
      maxsalary = max (maxsalary, salary) ;                                                                                             
      h.replace() ;                                                                                                                     
    end ;                                                                                                                               
  end ;                                                                                                                                 
  set have ;                                                                                                                            
  _iorc_ = h.find() ;                                                                                                                   
  avgsalary = &lt;FONT color="#0000FF"&gt;divide (sum, N)&lt;/FONT&gt; ;                                                                                                         
run ;                                                  
&lt;/PRE&gt;
&lt;P&gt;Note the advantage of using the DIVIDE function compared to the division operator: If the divisor is missing or zero, the function doesn't generate errors and/or warnings but simply an &lt;EM&gt;appropriate&lt;/EM&gt; missing value. That is, if the divisor is 0, it generates the special missing value &lt;STRONG&gt;.I&lt;/STRONG&gt; (standing for +infinity) if the numerator is positive and &lt;STRONG&gt;.M&lt;/STRONG&gt; (standing for -infinity) if it is negative; if the divisor is a standard missing value (aka "dot-blank"), a standard missing value is generated. (There're other variants listed in the documentation.)&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;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 05 Nov 2019 21:09:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601808#M174121</guid>
      <dc:creator>hashman</dc:creator>
      <dc:date>2019-11-05T21:09:26Z</dc:date>
    </item>
    <item>
      <title>Re: Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601813#M174122</link>
      <description>&lt;P&gt;This definitely solves my earlier question.&amp;nbsp; Really simple and a good trick to know.&amp;nbsp;&amp;nbsp;Thank you very much!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;However, I also have a follow up question.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Is there a way to calculate a statistic based on a subgroup of the main groups and then assign that statistic for every member of the main group.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For example, given a dataset....&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;DATA HAVE;&lt;BR /&gt;LENGTH JOBTYPE EDUCATION $16;&lt;BR /&gt;INPUT JOBTYPE $ EDUCATION $ SALARY;&lt;BR /&gt;&lt;BR /&gt;DATALINES;&lt;/P&gt;&lt;P&gt;Farmer High_School 50000&lt;BR /&gt;Farmer High_School 30000&lt;BR /&gt;Farmer College 45000&lt;BR /&gt;Farmer College 65000&lt;BR /&gt;Banker High_School 100000&lt;BR /&gt;Banker High_School 300000&lt;BR /&gt;Banker College 250000&lt;BR /&gt;Banker College 450000&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;CREATE THIS NEW DATASET....&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;JOBTYPE&amp;nbsp; &amp;nbsp; EDUCATION&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SALARY&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AVG_SALARY_HS&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; MAX_SALARY_HS&lt;BR /&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;High_School&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 50000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 40000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;50000&lt;BR /&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;High_School&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 30000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 40000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;50000&lt;BR /&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;College&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 45000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 40000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;50000&lt;BR /&gt;Farmer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;College&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 65000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 40000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;50000&lt;BR /&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;High_School&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 100000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;200000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 300000&lt;BR /&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;High_School&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 300000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;200000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 300000&lt;BR /&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;College&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 250000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;200000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 300000&lt;BR /&gt;Banker&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;College&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 450000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;200000&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 300000&lt;/P&gt;</description>
      <pubDate>Tue, 05 Nov 2019 21:14:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601813#M174122</guid>
      <dc:creator>whs278</dc:creator>
      <dc:date>2019-11-05T21:14:46Z</dc:date>
    </item>
    <item>
      <title>Re: Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601828#M174132</link>
      <description>Not easily in SQL, but PROC MEANS allows you to control the different levels of classifications using TYPES/WAYS statements and have more functionality.</description>
      <pubDate>Tue, 05 Nov 2019 21:44:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601828#M174132</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2019-11-05T21:44:58Z</dc:date>
    </item>
    <item>
      <title>Re: Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601831#M174134</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/279633"&gt;@whs278&lt;/a&gt;:&lt;/P&gt;
&lt;P&gt;Yes, it's easy. To account for a "subgroup", you only need to add that "subgroup" key to the key portion of the hash table - i.e. the portion whose hash variables are described by calling the DEFINEKEY method.&amp;nbsp;In this particular case, this "subgroup" is the education variable, and thus:&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;    h.definekey ("jobtype", "education") ;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Not a single other change is needed to be done to my code to work in this new case. In principle, it's no different from just adding another key to a GROUP BY clause in SQL. After another key is added, the hash object treats each distinct pair of &amp;nbsp;[jobtype,education] as a combined composite key-value and computes the aggregates accordingly. When they are merged back to the original data on the second pass (enacted by the second SET statement), the H.FIND() method looks up [jobtype,education] in the hash table for the values of both variables in the current record having just been read in. This is the default behavior since no keys are specified to FIND when it's called (the parentheses are empty), and so it auto-accepts the current PDV values of the variables defined in DEFINEDATA as the key-values to search for in the table.. &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.&lt;/P&gt;</description>
      <pubDate>Tue, 05 Nov 2019 21:48:28 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/601831#M174134</guid>
      <dc:creator>hashman</dc:creator>
      <dc:date>2019-11-05T21:48:28Z</dc:date>
    </item>
    <item>
      <title>Re: Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/602409#M174424</link>
      <description>Thank you Paul for the follow up response.&lt;BR /&gt;&lt;BR /&gt;However, I just want to clarify. Would your code calculate a separate average and maximum for each jobtype, education category? In other words, would it be equivalent to the following SQL code?&lt;BR /&gt;&lt;BR /&gt;CREATE TABLE WANT AS&lt;BR /&gt;SELECT AVG(SALARY), MAX(SALARY)&lt;BR /&gt;FROM HAVE&lt;BR /&gt;GROUP BY JOBTYPE, EDUCATION&lt;BR /&gt;&lt;BR /&gt;What I really want to do is calculate a maximum and average within each job type that only includes cases whose highest education level is High School. Then I want to assign those values to all the rows for that job type. So the AVG_SALARY_HS column would represent the average salary of cases whose highest education was a HS diploma grouped by category.&lt;BR /&gt;&lt;BR /&gt;For example, the $40,000 in the farmer category is the average of HS-educated farmers. However, I want to assign this $40,000 to all members of the parent group (i.e. all farmers) regardless of their education level. The HS suffix in the category name indicates that these values are derived only from the high school education level.&lt;BR /&gt;&lt;BR /&gt;It would basically be the same in SQL as first creating a table like this.&lt;BR /&gt;&lt;BR /&gt;CREATE TABLE WANT AS&lt;BR /&gt;SELECT AVG(SALARY) AS AVG_SALARY_HS,&lt;BR /&gt;MAX(SALARY) AS MAX_SALARY_HS&lt;BR /&gt;FROM HAVE&lt;BR /&gt;WHERE EDUCATION = "High_School"&lt;BR /&gt;GROUP BY JOBTYPE&lt;BR /&gt;&lt;BR /&gt;and then performing a one-to-many merge with the original dataset on the jobtype key only. In fact this what I did with my actual dataset. However, the dataset is very large, so I was wondering if using a data step would be more efficient.&lt;BR /&gt;&lt;BR /&gt;Again thank you for your help. I apologize for asking so many questions. However, I am dealing with large datasets with a lot of 'nested' data, so this issue comes up a lot.&lt;BR /&gt;</description>
      <pubDate>Thu, 07 Nov 2019 14:53:49 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/602409#M174424</guid>
      <dc:creator>whs278</dc:creator>
      <dc:date>2019-11-07T14:53:49Z</dc:date>
    </item>
    <item>
      <title>Re: Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/602436#M174437</link>
      <description>&lt;P&gt;You probably want to use CASE so you decide what values are fed to the aggregate function.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;CREATE TABLE WANT AS
SELECT JOBTYPE
     , AVG(case when (EDUCATION = "High_School") then SALARY else . end) as AVG_SALARY
FROM HAVE
GROUP BY JOBTYPE&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 07 Nov 2019 15:34:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/602436#M174437</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2019-11-07T15:34:56Z</dc:date>
    </item>
    <item>
      <title>Re: Mimic SQL Window Function in Data Step (MAX, AVG)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/602577#M174471</link>
      <description>&lt;P&gt;Thank you, Tom.&amp;nbsp; This gives the exact output that I want.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Still curious if it is possible to do the same thing using the Hash-Object Programming technique from Paul's code.&amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 07 Nov 2019 20:06:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mimic-SQL-Window-Function-in-Data-Step-MAX-AVG/m-p/602577#M174471</guid>
      <dc:creator>whs278</dc:creator>
      <dc:date>2019-11-07T20:06:07Z</dc:date>
    </item>
  </channel>
</rss>

