<?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: Filter observations based on two variables in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914606#M360403</link>
    <description>If each companyID has say 10+ userIDs and C1 or C2 may be present in all 10 or in none of them, would that affect the code?</description>
    <pubDate>Mon, 05 Feb 2024 23:42:44 GMT</pubDate>
    <dc:creator>curiosity</dc:creator>
    <dc:date>2024-02-05T23:42:44Z</dc:date>
    <item>
      <title>Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914589#M360396</link>
      <description>&lt;P&gt;Hi,&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have the following sample data:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;data have;
	input CompanyID	$ InvoiceAmount UserID $;
datalines;
A1	50 C1
A1	10	C7
A1	 5 	C3
B5	 100000 C3
B5	 10000 	C7
B5	 5000 	C2
B5	 1 	C1
D2	 100 	C2
D2	 50 	C2
D5	 1000 	C3
D5	 100 	C4
;
run;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is the dataset that I want:&lt;/P&gt;&lt;PRE&gt;data want;
	input CompanyID	$ InvoiceAmount UserID $;
datalines;
A1	 50 C1
B5	 5000 	C2
D2	 100 C2
D5	 1000 C3
;
run;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have multiple companyID in my have dataset but i need just one entry of each companyID in my want dataset with the following order of preferences on which to choose.&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Want should only have one row for each companyID&lt;/LI&gt;&lt;LI&gt;Want should take observation on each companyID that has userID of C1 or C2, if available.&lt;BR /&gt;If there are multiple C1 or C2 for a CompanyID, then take the observation that has the highest invoiceAmount of either C1 or C2.&lt;/LI&gt;&lt;LI&gt;If a specific companyID does not have userID of C1 or C2, then it should choose the observation that has the highest InvoiceAmount.&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;The data is already sorted on invoiceAmount by companyID.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Note: in the actual dataset theres about 10 million observations and each company might have 10 userIDs and C1 or C2 may be present in all 10 or in none of them.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Appreciate any help &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 05 Feb 2024 23:34:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914589#M360396</guid>
      <dc:creator>curiosity</dc:creator>
      <dc:date>2024-02-05T23:34:18Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914597#M360397</link>
      <description>&lt;P&gt;You could use code as below.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
 input CompanyID $ InvoiceAmount UserID $;
datalines;
A1 50 C1
A1 10 C7
A1  5  C3
B5  100000 C3
B5  10000  C7
B5  5000  C2
B5  1  C1
D2  100  C2
D2  50  C2
D5  1000  C3
D5  100  C4
;

proc sql;
  create view v_inter as
  select *
  from have
  order by 
    CompanyID
    ,case when UserID in ('C1','C2') then 1 else 2 end
    ,InvoiceAmount DESC
  ;
quit;

data want;
  set v_inter;
  by CompanyID;
  if first.CompanyID;
run;

proc print data=want;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Patrick_0-1707175039643.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/93282i04387D966AB4AE12/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Patrick_0-1707175039643.png" alt="Patrick_0-1707175039643.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Above code logic needs potentially some amendment for performance in case the data volumes in source table HAVE are really high or the table resides in a database. Please let us know if that's the case and provide further detail (data volumes/number of rows, database type and version).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 05 Feb 2024 23:20:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914597#M360397</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2024-02-05T23:20:17Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914599#M360398</link>
      <description>&lt;P&gt;I meant the want should be:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;PRE&gt;data want;
	input CompanyID	$ InvoiceAmount UserID $;
datalines;
A1	 50 C1
B5	 5000 	C2
D2	 100 C2
D5	 1000 C3
;
run;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;But I see Patrick already knew what I meant!&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;In my original version I had the condition that it should choose first the highest between C1 then if no C1 is present then to choose highest C2.&amp;nbsp;Then if no (C1 or C2) then choose the highest invoiceAmount of any of the remainder userIDs.&amp;nbsp; &amp;nbsp;But for my requirement I realized I'm okay with the highest observation of C1 or C2 if either is present.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 05 Feb 2024 23:28:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914599#M360398</guid>
      <dc:creator>curiosity</dc:creator>
      <dc:date>2024-02-05T23:28:06Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914600#M360399</link>
      <description>&lt;P&gt;Thank you for your reply.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Would you happen to know how to solve this using data steps intead of procSQL or is it that its more efficient using procsql? I dont have a lot of experience with procsql.. but i'll use it if its more efficient.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The dataset is about 10 million observations currently stored in a standard SAS 9.4 dataset.&lt;/P&gt;</description>
      <pubDate>Mon, 05 Feb 2024 23:31:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914600#M360399</guid>
      <dc:creator>curiosity</dc:creator>
      <dc:date>2024-02-05T23:31:34Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914601#M360400</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;In my original version I had the condition that it should choose first the highest between C1 then if no C1 is present then to choose highest C2.&amp;nbsp;Then if no (C1 or C2) then choose the highest invoiceAmount of any of the remainder userIDs.&amp;nbsp; &amp;nbsp;But for my requirement I realized I'm okay with the highest observation of C1 or C2 if either is present.&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If you want to revert back to your original selection logic then just change the CASE logic&lt;/P&gt;
&lt;PRE&gt;    ,case when UserID ='C1' then 1 when UserID ='C2' then 1 else 3 end
&lt;/PRE&gt;</description>
      <pubDate>Mon, 05 Feb 2024 23:32:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914601#M360400</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2024-02-05T23:32:16Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914602#M360401</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/187523"&gt;@curiosity&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;Thank you for your reply.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Would you happen to know how to solve this using data steps intead of procSQL or is it that its more efficient using procsql? I dont have a lot of experience with procsql.. but i'll use it if its more efficient.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The dataset is about 10 million observations currently stored in a standard SAS 9.4 dataset.&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;SQL for the case here is more efficient from a coding/line of code perspective but it does internal sorting and sorting normally requires quite a bit of resources.&lt;/P&gt;</description>
      <pubDate>Mon, 05 Feb 2024 23:34:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914602#M360401</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2024-02-05T23:34:48Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914606#M360403</link>
      <description>If each companyID has say 10+ userIDs and C1 or C2 may be present in all 10 or in none of them, would that affect the code?</description>
      <pubDate>Mon, 05 Feb 2024 23:42:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914606#M360403</guid>
      <dc:creator>curiosity</dc:creator>
      <dc:date>2024-02-05T23:42:44Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914608#M360405</link>
      <description>&lt;P&gt;Below code uses a data step and takes advantage of the known sort order of your source data.&lt;/P&gt;
&lt;P&gt;Because there is no need for additional sorting this code version should outperform any other approach that requires sorting.&lt;/P&gt;
&lt;P&gt;In the code below C1 customers get priority over C2 customers. If you don't care then just amend the code and combine the logic for the two to only populate and use a variable&amp;nbsp;&lt;EM&gt;_point_c&lt;/EM&gt;.&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
 input CompanyID $ InvoiceAmount UserID $;
datalines;
A1 50 C1
A1 10 C7
A1  5  C3
B5  100000 C3
B5  10000  C7
B5  5000  C2
B5  1  C1
D2  100  C2
D2  50  C2
D5  1000  C3
D5  100  C4
;

/* The data is already sorted on invoiceAmount by companyID. */
proc sort data=have;
  by CompanyID InvoiceAmount;
run;

data want(drop=_:);
  set have;
  by CompanyID InvoiceAmount;
  retain _point_c1 _point_c2;

  if UserID in ('C1') then _point_c1 = _n_;
  else 
  if UserID in ('C2') then _point_c2 = _n_;

  if last.CompanyID then
    do;
      _point=coalesce(_point_c1,_point_c2,_n_);
      set have point=_point;
      output;
      call missing(of _point_c:);
    end;
run;

proc print data=want;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN&gt;If each companyID has say 10+ userIDs and C1 or C2 may be present in all 10 or in none of them, would that affect the code?&lt;/SPAN&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN&gt;The only thing that affects the code is that we need to treat C1 &amp;amp; C2 customers differently to the rest by giving them priority.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 06 Feb 2024 09:44:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914608#M360405</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2024-02-06T09:44:31Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914640#M360418</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
	input CompanyID	$ InvoiceAmount UserID $;
datalines;
A1	50 C1
A1	10	C7
A1	 5 	C3
B5	 100000 C3
B5	 10000 	C7
B5	 5000 	C2
B5	 1 	C1
D2	 100 	C2
D2	 50 	C2
D5	 1000 	C3
D5	 100 	C4
;
run;

data temp;
 set have;
 flag=not (UserID in ('C1' 'C2'));
run;
proc sort data=temp out=temp1 ;
by CompanyID flag descending InvoiceAmount;
run;
proc sort data=temp1 out=temp2 nodupkey;
by CompanyID flag ;
run;
proc sort data=temp2 out=want nodupkey;
by CompanyID  ;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 06 Feb 2024 06:48:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914640#M360418</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2024-02-06T06:48:21Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914729#M360455</link>
      <description>&lt;P&gt;Sorting and judicious use of the "WHERE=" data set name parameter appears to be the simplest:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
 input CompanyID $ InvoiceAmount UserID $;
datalines;
A1 50 C1
A1 10 C7
A1  5  C3
B5  100000 C3
B5  10000  C7
B5  5000  C2
B5  1  C1
D2  100  C2
D2  50  C2
D5  1000  C3
D5  100  C4
;

proc sort data=have out=need;
  by companyid descending invoiceamount;
run;

data want;
  set need (where=(userid in ('C1','C2'))      )
      need (where=(not(userid in ('C1','C2'))) );
  by companyid;
  if first.companyid;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The where= params force all the "C1" or "C2" obs to precede all the others for a given companyid.&amp;nbsp; And since the data are sorted by descending invoice, the where= means the largest C1/C2 invoice will be first, even if there are larger non C1/C2 observations.&lt;/P&gt;</description>
      <pubDate>Tue, 06 Feb 2024 17:24:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914729#M360455</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-02-06T17:24:02Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914735#M360461</link>
      <description>&lt;P&gt;If sorting by companyid/descending invoiceamount is expensive, or you just want to avaid a proc sort, you can keep track of the max value for each id, reserving a variable for C1/C2 obs and for all obs.&amp;nbsp; At the end of the id, just re-read and output the obs that has the maximum qualifying invoice.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Of course, this assumes that the data are sorted by companyid:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want (drop=_:);
  set have;
  by companyid;
  retain _max1  _n_max1  /*Track C!/C2 obs only*/
         _max2  _n_max2  /*Track all obs */;
  if first.companyid then call missing (of _:);
  if userid in ('C1','C2') and invoiceamount &amp;gt; _max1 then do;
     _max1=invoiceamount;
     _n_max1=_n_;
  end;
  if invoiceamount &amp;gt; _max2 then do;
     _max2=invoiceamount;
     _n_max2=_n_;
  end;
  if last.companyid;
  _n_max=coalesce(_n_max1,_n_max2);
  set have point=_n_max;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 06 Feb 2024 18:24:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914735#M360461</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-02-06T18:24:58Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914823#M360504</link>
      <description>&lt;P&gt;As your data is already sorted by CompanyID and descending InvoiceAmount, this should do it:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
  set 
    have(where=(UserID in('C1','C2')))
    have(where=(UserID not in('C1','C2')))
    ;
  by CompanyID;
  if first.CompanyID;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 07 Feb 2024 06:46:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/914823#M360504</guid>
      <dc:creator>s_lassen</dc:creator>
      <dc:date>2024-02-07T06:46:44Z</dc:date>
    </item>
    <item>
      <title>Re: Filter observations based on two variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/915177#M360619</link>
      <description>&lt;P&gt;Appreciate all the suggestions!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I tested them all and they of course all worked.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I used the last one since it was the simplest for me to understand.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thank you all &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 08 Feb 2024 23:35:00 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Filter-observations-based-on-two-variables/m-p/915177#M360619</guid>
      <dc:creator>curiosity</dc:creator>
      <dc:date>2024-02-08T23:35:00Z</dc:date>
    </item>
  </channel>
</rss>

