<?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: Transpose, concat and filter in Proc SQL in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631509#M187119</link>
    <description>&lt;P&gt;Other approach, assuming `name_i` is sorted:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input name_i $ name_d $;
datalines;
A a 
A b 
A a
B c
B c
B c
C d
C a
C b
D d
;
run;

data want(drop=__:);

  declare hash U();
  U.defineKey("name_i");
  U.defineKey("__tmp");
  U.defineDone();

  declare hash H(multidata:"Y");
  H.defineKey("name_i");
  H.defineData("__tmp");
  H.defineDone();

  do until(last.name_i);
    set have(rename=(name_d=__tmp));
    by name_i;
    __key=name_i;
    if U.check() then do; H.add(key:__key, data: __tmp); U.add(); end;
  end;

  H.reset_dup();
  length name_d $ 200; retain name_d;
  name_d = "";
  do while(h.do_over(key:__key) = 0);
    name_d = catx(", ", name_d, __tmp);
  end;
  H.delete();
  U.delete();

run;
proc print;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;All the best&lt;/P&gt;&lt;P&gt;Bart&lt;/P&gt;</description>
    <pubDate>Thu, 12 Mar 2020 10:25:06 GMT</pubDate>
    <dc:creator>yabwon</dc:creator>
    <dc:date>2020-03-12T10:25:06Z</dc:date>
    <item>
      <title>Transpose, concat and filter in Proc SQL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631488#M187103</link>
      <description>&lt;P&gt;Hello Dear Colleagues!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Could you please tell me if it is possible to transpose, concat(&lt;SPAN&gt;delimiter=any)&lt;/SPAN&gt;&amp;nbsp;and filter data in SAS Proc SQL?&lt;/P&gt;&lt;P&gt;Or such operations could be done only in datastep?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;data have;
input name_i name_d;
datalines;
A a 
A b 
A a&lt;BR /&gt;B c&lt;BR /&gt;B c&lt;BR /&gt;B c&lt;BR /&gt;C d&lt;BR /&gt;C a&lt;BR /&gt;C b&lt;BR /&gt;D d&lt;BR /&gt;;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;data want;
input name_i name_d;
datalines;
A a, b 
B c&lt;BR /&gt;C d, a, b&lt;BR /&gt;D c&lt;BR /&gt;;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;</description>
      <pubDate>Thu, 12 Mar 2020 09:28:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631488#M187103</guid>
      <dc:creator>Ivan555</dc:creator>
      <dc:date>2020-03-12T09:28:37Z</dc:date>
    </item>
    <item>
      <title>Re: Transpose, concat and filter in Proc SQL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631501#M187113</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;try this:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input name_i $ name_d $; n=_N_;
datalines;
A a 
A b 
A a
B c
B c
B c
C d
C a
C b
D d
;
run;
proc sort data = have;
  by name_i name_d n;
run;

/* if you need to keep the order form the original dataset uncomment below */
/*
data have;
  set have;
  by name_i name_d;
  if first.name_d;
run;
proc sort data = have;
  by name_i n;
run;
*/

data want(drop=__:);
  set have(rename=(name_d=__tmp) drop = n);
  by name_i __tmp;
  length name_d $ 200; retain name_d;
  if first.name_i then name_d = "";
  if first.__tmp then name_d = catx(", ", name_d, __tmp);
  if last.name_i;
run;
proc print;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;All the best&lt;/P&gt;&lt;P&gt;Bart&lt;/P&gt;</description>
      <pubDate>Thu, 12 Mar 2020 10:00:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631501#M187113</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2020-03-12T10:00:45Z</dc:date>
    </item>
    <item>
      <title>Re: Transpose, concat and filter in Proc SQL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631505#M187116</link>
      <description>&lt;P&gt;A lot of other SQL dialects have functions for aggregating strings across rows (e.g. STRING_AGG in MS SQL), but SAS missed out on that one. I am not sure why, it should not be that hard to expand the CAT family functions in the same way that e.g. SUM and MIN are expanded in SAS SQL.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can do it in SQL, but the code becomes rather tedious:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql;
  create table want as select
     all.name_i, 
     catx(', ',a.name_d,b.name_d,c.name_d,d.name_d) as name_d
   from
     (select distinct name_i from have) all left join
     (select distinct name_d from have where name_d='a') a 
         on all.name_i=a.name_i left join
     (select distinct name_d from have where name_d='b') b 
         on all.name_i=b.name_i left join
     (select distinct name_d from have where name_d='c') c 
         on all.name_i=c.name_i left join
     (select distinct name_d from have where name_d='c') d 
         on all.name_i=d.name_i
     ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You could write a macro to do something like that with any NAME_D values, but I would recommend against it. A datastep is much faster and easier to understand:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sort data=have;
  by name_i name_d;
run;

data want;
  do until last.name_i;
    set have;
    by name_i name_d;
    if first.name_d then
      new_d=catx(', ',new_d,name_d);
    end;
  drop name_d;
  rename new_d=name_d;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 12 Mar 2020 10:17:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631505#M187116</guid>
      <dc:creator>s_lassen</dc:creator>
      <dc:date>2020-03-12T10:17:42Z</dc:date>
    </item>
    <item>
      <title>Re: Transpose, concat and filter in Proc SQL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631509#M187119</link>
      <description>&lt;P&gt;Other approach, assuming `name_i` is sorted:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input name_i $ name_d $;
datalines;
A a 
A b 
A a
B c
B c
B c
C d
C a
C b
D d
;
run;

data want(drop=__:);

  declare hash U();
  U.defineKey("name_i");
  U.defineKey("__tmp");
  U.defineDone();

  declare hash H(multidata:"Y");
  H.defineKey("name_i");
  H.defineData("__tmp");
  H.defineDone();

  do until(last.name_i);
    set have(rename=(name_d=__tmp));
    by name_i;
    __key=name_i;
    if U.check() then do; H.add(key:__key, data: __tmp); U.add(); end;
  end;

  H.reset_dup();
  length name_d $ 200; retain name_d;
  name_d = "";
  do while(h.do_over(key:__key) = 0);
    name_d = catx(", ", name_d, __tmp);
  end;
  H.delete();
  U.delete();

run;
proc print;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;All the best&lt;/P&gt;&lt;P&gt;Bart&lt;/P&gt;</description>
      <pubDate>Thu, 12 Mar 2020 10:25:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/631509#M187119</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2020-03-12T10:25:06Z</dc:date>
    </item>
    <item>
      <title>Re: Transpose, concat and filter in Proc SQL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/632614#M187569</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/76464"&gt;@s_lassen&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you very much, but unfortunately your code is not working properly. Maybe that is my fault, but I am getting errors while compiling it and&amp;nbsp; cannot understand what I am doing wrong. I'm sorry..&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/35763"&gt;@yabwon&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you very much, i've resend your code to my colleguaes(people, which asked me about this problem), they transmitted big thanks to you.&lt;/P&gt;</description>
      <pubDate>Tue, 17 Mar 2020 11:04:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/632614#M187569</guid>
      <dc:creator>Ivan555</dc:creator>
      <dc:date>2020-03-17T11:04:22Z</dc:date>
    </item>
    <item>
      <title>Re: Transpose, concat and filter in Proc SQL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/632617#M187570</link>
      <description>&lt;P&gt;Glad I could help &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Bart&lt;/P&gt;</description>
      <pubDate>Tue, 17 Mar 2020 11:13:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Transpose-concat-and-filter-in-Proc-SQL/m-p/632617#M187570</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2020-03-17T11:13:22Z</dc:date>
    </item>
  </channel>
</rss>

