<?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: Loop between two columns in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497546#M131894</link>
    <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/138264"&gt;@Amr_Alaaeldin&lt;/a&gt;&amp;nbsp;if the proc sort is right as did by RW, I think this is pretty straight forward assuming my understanding is right&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have; 
infile cards truncover;
  input cust_id $3. exist_account $3. new_account $4.; 
datalines;
003 CA CB
002 BB BC
002 BC 
001 AA AB
003 DC DD
001 AC AD
001 AD AE
003 CB CC
003 DD 
003 DB DC
003 DA DB
002 BA BB
001 AE 
001 AB AC
003 CC 
004 AA
;
run;

proc sort data=have out=_have;
  by cust_id exist_account;
run;

data want;
set _have;
by cust_id exist_account;
array t(10) $ _temporary_;/*arbitrary subscript, should assign something large like 9999*/
retain First_Account;
if first.cust_id then do; First_Account=exist_account;Replacement_Count=0;end;
if first.cust_id and missing(new_account) then 
	do;
		last_account=exist_account;
		output;
	end;
else if not missing(new_account) and (new_account not in t) then
	do; 
		if Replacement_Count=0 then First_Account=exist_account;
		Replacement_Count+1;
		t(Replacement_Count)=new_account;
	end;
else if   missing(new_account) then 
	do;
		last_account=exist_account;
		output;
		Replacement_Count=0;
		call missing(of t(*));
	end;
keep cust_id First_Account last_account Replacement_Count;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Thu, 20 Sep 2018 21:02:10 GMT</pubDate>
    <dc:creator>novinosrin</dc:creator>
    <dc:date>2018-09-20T21:02:10Z</dc:date>
    <item>
      <title>Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496835#M131511</link>
      <description>&lt;P&gt;Hello&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I need your appreciated assistance in the below case&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a data set includes three columns Customer ID , Existing Account and New Account , the existing account could be replaced with the new account and the new account will open a new record to be a existing account , and the account may be replaced many times . Like below&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;Data have ; 
input Cust_ID $3. Exist_Account $3. New_Account $4.; 
datalines;
003 CA CB
002 BB BC
002 BC 
001 AA AB
003 DC DD
001 AC AD
001 AD AE
003 CB CC
003 DD 
003 DB DC
003 DA DB
002 BA BB
001 AE 
001 AB AC
003 CC 
;
Run ;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;for example :&amp;nbsp;Existing Account "AA" replaced by new account "AB" and "AB" opened a new record to be existing account then "AB" Replaced by "AC" &amp;nbsp;and&amp;nbsp;&lt;SPAN&gt;"AC" opened a new record to be existing account then "AC" Replaced by "AD" and&amp;nbsp;"AD" opened a new record to be existing account then "AD" Replaced by "AE" and&amp;nbsp;"AE" opened a new record to be existing account .&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;TABLE&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;Cust_ID&amp;nbsp;&lt;/TD&gt;&lt;TD&gt;Exist_Account&lt;/TD&gt;&lt;TD&gt;New_Account&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;CA&lt;/TD&gt;&lt;TD&gt;CB&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;002&lt;/TD&gt;&lt;TD&gt;BB&lt;/TD&gt;&lt;TD&gt;BC&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;002&lt;/TD&gt;&lt;TD&gt;BC&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;001&lt;/TD&gt;&lt;TD&gt;AA&lt;/TD&gt;&lt;TD&gt;AB&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;DC&lt;/TD&gt;&lt;TD&gt;DD&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;001&lt;/TD&gt;&lt;TD&gt;AC&lt;/TD&gt;&lt;TD&gt;AD&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;001&lt;/TD&gt;&lt;TD&gt;AD&lt;/TD&gt;&lt;TD&gt;AE&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;CB&lt;/TD&gt;&lt;TD&gt;CC&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;DD&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;DB&lt;/TD&gt;&lt;TD&gt;DC&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;DA&lt;/TD&gt;&lt;TD&gt;DB&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;002&lt;/TD&gt;&lt;TD&gt;BA&lt;/TD&gt;&lt;TD&gt;BB&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;001&lt;/TD&gt;&lt;TD&gt;AE&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;001&lt;/TD&gt;&lt;TD&gt;AB&lt;/TD&gt;&lt;TD&gt;AC&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;CC&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;the results should be like the below:&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;TABLE&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;Cust_ID&amp;nbsp;&lt;/TD&gt;&lt;TD&gt;First_Account&lt;/TD&gt;&lt;TD&gt;Last_Account&lt;/TD&gt;&lt;TD&gt;Replacement_Count&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;001&lt;/TD&gt;&lt;TD&gt;AA&lt;/TD&gt;&lt;TD&gt;AE&lt;/TD&gt;&lt;TD&gt;4&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;002&lt;/TD&gt;&lt;TD&gt;BA&lt;/TD&gt;&lt;TD&gt;BC&lt;/TD&gt;&lt;TD&gt;2&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;CA&lt;/TD&gt;&lt;TD&gt;CC&lt;/TD&gt;&lt;TD&gt;2&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;003&lt;/TD&gt;&lt;TD&gt;DA&lt;/TD&gt;&lt;TD&gt;DD&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you ...&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 19 Sep 2018 07:37:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496835#M131511</guid>
      <dc:creator>Amr_Alaaeldin</dc:creator>
      <dc:date>2018-09-19T07:37:43Z</dc:date>
    </item>
    <item>
      <title>Re: Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496840#M131514</link>
      <description>&lt;P&gt;I wasn't sure about the extra split in 003, but this is nearly there, you can add the other restriction, maybe by adding another grouping variable to the data.&lt;/P&gt;
&lt;PRE&gt;data have; 
  input cust_id $3. exist_account $3. new_account $4.; 
datalines;
003 CA CB
002 BB BC
002 BC 
001 AA AB
003 DC DD
001 AC AD
001 AD AE
003 CB CC
003 DD 
003 DB DC
003 DA DB
002 BA BB
001 AE 
001 AB AC
003 CC 
;
run;

proc sort data=have out=want;
  by cust_id exist_account;
run;

data want;
  set want;
  retain replacement_count first_account;
  by cust_id;
  if first.cust_id then do;
    first_account=exist_account;
    if new_account ne "" then replacement_count=sum(replacement_count,1);
  end;
  else if last.cust_id then do;
    last_account=exist_account;
    output;
  end;
  else if new_account ne "" then replacement_count=sum(replacement_count,1);
run;
    &lt;/PRE&gt;</description>
      <pubDate>Wed, 19 Sep 2018 08:04:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496840#M131514</guid>
      <dc:creator>RW9</dc:creator>
      <dc:date>2018-09-19T08:04:14Z</dc:date>
    </item>
    <item>
      <title>Re: Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496849#M131517</link>
      <description>Thank you .. But still have an issues with Cust_id "003" because this customer has 2 different accounts and every one replaced many times ..&lt;BR /&gt;so i am expecting to don't use the customer id .. and use only the existing account and new account .&lt;BR /&gt;Thanks a lot</description>
      <pubDate>Wed, 19 Sep 2018 08:31:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496849#M131517</guid>
      <dc:creator>Amr_Alaaeldin</dc:creator>
      <dc:date>2018-09-19T08:31:12Z</dc:date>
    </item>
    <item>
      <title>Re: Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496850#M131518</link>
      <description>&lt;P&gt;Please re-read what I posted:&lt;/P&gt;
&lt;P&gt;"&lt;/P&gt;
&lt;P&gt;I wasn't sure about the extra split in 003, but this is nearly there, you can add the other restriction, maybe by adding another grouping variable to the data.&lt;/P&gt;
&lt;P&gt;"&lt;/P&gt;
&lt;P&gt;I do not know about the split in cust 3 - as I suggested you should add some information into the dataset to indicate a new account, maybe something like:&lt;BR /&gt;cust_id&amp;nbsp; &amp;nbsp;account&amp;nbsp; &amp;nbsp;exist_account ...&lt;/P&gt;
&lt;P&gt;003&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/P&gt;
&lt;P&gt;003&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;2&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then where I use just by cust_id, you would add in by cust_id account, and do first/last from that.&amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 19 Sep 2018 08:34:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496850#M131518</guid>
      <dc:creator>RW9</dc:creator>
      <dc:date>2018-09-19T08:34:35Z</dc:date>
    </item>
    <item>
      <title>Re: Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496957#M131565</link>
      <description>&lt;P&gt;Are you sure it is one to one match ?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have; 
  input cust_id $3. exist_account $3. new_account $4.; 
datalines;
003 CA CB
002 BB BC
002 BC 
001 AA AB
003 DC DD
001 AC AD
001 AD AE
003 CB CC
003 DD 
003 DB DC
003 DA DB
002 BA BB
001 AE 
001 AB AC
003 CC 
;
run;
proc sql;
create table ancentor as
select * from have
 where exist_account not in 
 (select new_account from have)
 order by 1;
quit;
data want;
 if _n_=1 then do;
  declare hash h(dataset:'have(where=(exist_account is not missing and 
  new_account is not missing))');
  h.definekey('exist_account');
  h.definedata('new_account');
  h.definedone();
 end;
set ancentor;
fist=exist_account;
count=0;
 do until(rc ne 0);
  call missing(new_account);
  rc=h.find();
  if rc=0 then do;exist_account=new_account;count+1;last=new_account;end;
 end;
drop exist_account new_account rc;
run;
proc print;run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 19 Sep 2018 13:18:49 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/496957#M131565</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2018-09-19T13:18:49Z</dc:date>
    </item>
    <item>
      <title>Re: Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497295#M131760</link>
      <description>Thanks .. It works .. but the the performance is very slow because I performed it on big dataset include 500,000 records .. and I started to run it yesterday and it still running till now .</description>
      <pubDate>Thu, 20 Sep 2018 10:08:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497295#M131760</guid>
      <dc:creator>Amr_Alaaeldin</dc:creator>
      <dc:date>2018-09-20T10:08:16Z</dc:date>
    </item>
    <item>
      <title>Re: Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497337#M131785</link>
      <description>&lt;P&gt;&lt;SPAN&gt;500,000 records is small dataset as my opinion .&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;You must run into a dead loop like :&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;003 CA CB&lt;BR /&gt;002 CB CA&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Try this one : (Edited)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;
proc sql;
create table ancentor as
select * from have
 where exist_account not in 
 (select new_account from have)
 order by 1;
quit;
data want;
 if _n_=1 then do;
  declare hash h(dataset:'have(where=(exist_account is not missing and 
  new_account is not missing))');
  h.definekey('exist_account');
  h.definedata('new_account');
  h.definedone();
 
  length kk $ 80;
  declare hash k();
  k.definekey('kk');
  k.definedone();
 end;
set ancentor;
fist=exist_account;
count=0;
 do until(rc ne 0 or rx = 0);
  if not missing(exist_account) then do;kk=exist_account; k.replace();end;
  call missing(new_account);
  rc=h.find();
  rx=k.check(key:new_account);
  if rc=0 then do;exist_account=new_account;if rx ne 0 then do;count+1;last=new_account;end;end;
 end;
k.clear();
drop exist_account new_account rc kk rx;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 20 Sep 2018 13:04:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497337#M131785</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2018-09-20T13:04:36Z</dc:date>
    </item>
    <item>
      <title>Re: Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497463#M131860</link>
      <description>Thanks you Ksharp very much appreciated.. Perfect</description>
      <pubDate>Thu, 20 Sep 2018 17:03:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497463#M131860</guid>
      <dc:creator>Amr_Alaaeldin</dc:creator>
      <dc:date>2018-09-20T17:03:05Z</dc:date>
    </item>
    <item>
      <title>Re: Loop between two columns</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497546#M131894</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/138264"&gt;@Amr_Alaaeldin&lt;/a&gt;&amp;nbsp;if the proc sort is right as did by RW, I think this is pretty straight forward assuming my understanding is right&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have; 
infile cards truncover;
  input cust_id $3. exist_account $3. new_account $4.; 
datalines;
003 CA CB
002 BB BC
002 BC 
001 AA AB
003 DC DD
001 AC AD
001 AD AE
003 CB CC
003 DD 
003 DB DC
003 DA DB
002 BA BB
001 AE 
001 AB AC
003 CC 
004 AA
;
run;

proc sort data=have out=_have;
  by cust_id exist_account;
run;

data want;
set _have;
by cust_id exist_account;
array t(10) $ _temporary_;/*arbitrary subscript, should assign something large like 9999*/
retain First_Account;
if first.cust_id then do; First_Account=exist_account;Replacement_Count=0;end;
if first.cust_id and missing(new_account) then 
	do;
		last_account=exist_account;
		output;
	end;
else if not missing(new_account) and (new_account not in t) then
	do; 
		if Replacement_Count=0 then First_Account=exist_account;
		Replacement_Count+1;
		t(Replacement_Count)=new_account;
	end;
else if   missing(new_account) then 
	do;
		last_account=exist_account;
		output;
		Replacement_Count=0;
		call missing(of t(*));
	end;
keep cust_id First_Account last_account Replacement_Count;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 20 Sep 2018 21:02:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-between-two-columns/m-p/497546#M131894</guid>
      <dc:creator>novinosrin</dc:creator>
      <dc:date>2018-09-20T21:02:10Z</dc:date>
    </item>
  </channel>
</rss>

