<?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: Replacing values based on others rows value in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567176#M159466</link>
    <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/151178"&gt;@ASHISH2525&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One way to achieve this is a double "DOW loop":&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want(drop=flag);
do until(last.type);
  set one;
  by type;
  if mvalue='Progress' then flag=1;
end;
do until(last.type);
  set one;
  by type;
  if flag then mvalue='Progress';
  output;
end;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Wed, 19 Jun 2019 09:06:27 GMT</pubDate>
    <dc:creator>FreelanceReinh</dc:creator>
    <dc:date>2019-06-19T09:06:27Z</dc:date>
    <item>
      <title>Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567164#M159462</link>
      <description>&lt;P&gt;Hi All,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I need to update one columns value based on other rows specific value.&lt;/P&gt;&lt;P&gt;in below data set i want to update Mvalue as "Progress" for all the rows of a type if any single row contains "Progress" in Mvalue.&lt;/P&gt;&lt;P&gt;eg: if type C contains Mvalue as "&lt;CODE class=" language-sas"&gt;Progress&lt;/CODE&gt;"&amp;nbsp; then for all the rows of type "C" should be tagged as "&lt;CODE class=" language-sas"&gt;Progress&lt;/CODE&gt;" in Mvalue.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data one;

input type $  Mvalue $12.;


datalines;

A closed

B Progress

C Closed

C Progress

C Closed

E closed

E Closed

E Progress

;

run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Ashish&lt;/P&gt;</description>
      <pubDate>Wed, 19 Jun 2019 08:28:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567164#M159462</guid>
      <dc:creator>ASHISH2525</dc:creator>
      <dc:date>2019-06-19T08:28:42Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567176#M159466</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/151178"&gt;@ASHISH2525&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One way to achieve this is a double "DOW loop":&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want(drop=flag);
do until(last.type);
  set one;
  by type;
  if mvalue='Progress' then flag=1;
end;
do until(last.type);
  set one;
  by type;
  if flag then mvalue='Progress';
  output;
end;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 19 Jun 2019 09:06:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567176#M159466</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2019-06-19T09:06:27Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567177#M159467</link>
      <description>&lt;P&gt;One way&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data one;
input type $  Mvalue $12.;
datalines;
A closed
B Progress
C Closed
C Progress
C Closed
E closed
E Closed
E Progress
;
run;

data two;
   flag=0;
   do until (last.type);
      set one;
      by type;
      if Mvalue='Progress' then flag=1;
   end;
   do until (last.type);
      set one;
      by type;
      if flag=1 then Mvalue='Progress';
      output;
   end;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 19 Jun 2019 09:06:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567177#M159467</guid>
      <dc:creator>PeterClemmensen</dc:creator>
      <dc:date>2019-06-19T09:06:57Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567180#M159468</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32733"&gt;@FreelanceReinh&lt;/a&gt;&amp;nbsp;beat me by 30 sec and a few lines &lt;span class="lia-unicode-emoji" title=":winking_face:"&gt;😉&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 19 Jun 2019 09:07:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567180#M159468</guid>
      <dc:creator>PeterClemmensen</dc:creator>
      <dc:date>2019-06-19T09:07:53Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567190#M159470</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/31304"&gt;@PeterClemmensen&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32733"&gt;@FreelanceReinh&lt;/a&gt;&amp;nbsp;beat me by 30 sec and a few lines &lt;span class="lia-unicode-emoji" title=":winking_face:"&gt;😉&lt;/span&gt;&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;It's not easy to beat someone as fast as you. &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;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/151178"&gt;@ASHISH2525&lt;/a&gt;: So, this solution has been confirmed independently. Other possible approaches include PROC SQL (using&amp;nbsp;&lt;FONT face="courier new,courier"&gt;group by type&lt;/FONT&gt;&amp;nbsp;and &lt;FONT face="courier new,courier"&gt;max(mvalue='Progress')&lt;/FONT&gt;, but with the drawback that the order of observations within a TYPE value is not maintained) and a "self merge" DATA step (with the drawback that the ugly note "&lt;FONT face="courier new,courier"&gt;MERGE statement has more than one data set with repeats of BY values&lt;/FONT&gt;" may appear in the log, which could be avoided with a preliminary step, though).&lt;/P&gt;</description>
      <pubDate>Wed, 19 Jun 2019 09:24:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567190#M159470</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2019-06-19T09:24:46Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567234#M159491</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data one;
input type $  Mvalue $12.;
datalines;
A closed
B Progress
C Closed
C Progress
C Closed
E closed
E Closed
E Progress
;
data want;
 merge one one(keep=type  Mvalue where=(_Mvalue='Progress') rename=(Mvalue=_Mvalue));
 by type;
 want_Mvalue=coalescec(_Mvalue,Mvalue);
 drop _Mvalue Mvalue;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 19 Jun 2019 12:48:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567234#M159491</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2019-06-19T12:48:06Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567241#M159493</link>
      <description>&lt;P&gt;Yes, this is the "self merge" approach, my version of which was this:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want(drop=_m);
merge one(rename=(mvalue=_m))
      one(where=(mvalue='Progress') in=p);
by type;
if ~p then mvalue=_m;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;As mentioned in my previous post, it has the disadvantage of potentially producing that unwanted note about "more than one data set with repeats of BY values" &lt;EM&gt;if&lt;/EM&gt; there is a BY group containing more than one observation with &lt;FONT face="courier new,courier"&gt;mvalue='Progress'&lt;/FONT&gt;&amp;nbsp;in dataset ONE. But it works properly in spite of that note.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 19 Jun 2019 13:02:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567241#M159493</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2019-06-19T13:02:21Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567248#M159494</link>
      <description>&lt;P&gt;OK.&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32733"&gt;@FreelanceReinh&lt;/a&gt;&amp;nbsp; ,&lt;/P&gt;
&lt;P&gt;I just want put it further for fun.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data one;
input type $  Mvalue $12.;
datalines;
A closed
B Progress
C Closed
C Progress
C Closed
E closed
E Closed
E Progress
;
proc sql;
create table want as
select 	*,case when sum(Mvalue='Progress') then  'Progress' else Mvalue end as Want_Mvalue
 from one 
  group by type
;
quit;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 19 Jun 2019 13:09:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567248#M159494</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2019-06-19T13:09:47Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567292#M159514</link>
      <description>&lt;P&gt;Now that we have "all" three major approaches on the table, it would be interesting to see how they perform on a larger input dataset. So, let's create one:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Create a larger test dataset */

data one(drop=i j);
length type $8 mvalue $12;
call streaminit(27182818);
do i=1 to 1e7;
  type=put(i, hex8.);
  do j=1 to rand('integer',10);
    mvalue=choosec(rand('integer',4),'closed','Progress','Closed','other');
    output;
  end;
end;
run; /* 54995649 obs. */&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The log under the spoiler below shows the run times ("real time") on my workstation:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;FONT face="courier new,courier"&gt;DOW loop approach:&amp;nbsp; &amp;nbsp; 8.19 s&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face="courier new,courier"&gt;Self merge approach:&amp;nbsp; 9.83 s&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face="courier new,courier"&gt;PROC SQL approach:&amp;nbsp; &amp;nbsp;17.15 s&lt;/FONT&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The above ranking was confirmed in a second run (8.57 s, 9.82 s, 16.47 s) and in a third run with the order of the three steps reversed (8.65 s, 9.73 s, 16.74 s).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To be fair, it should be noted that the PROC SQL approach does not require a sorted (or indexed) input dataset (&lt;FONT face="courier new,courier"&gt;by type&lt;/FONT&gt;), unlike the other two approaches. With a randomly sorted version of input dataset ONE it took about 32 - 33 s.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-SPOILER&gt;
&lt;PRE&gt;1    data one(drop=i j);
2    length type $8 mvalue $12;
3    call streaminit(27182818);
4    do i=1 to 1e7;
5      type=put(i, hex8.);
6      do j=1 to rand('integer',10);
7        mvalue=choosec(rand('integer',4),'closed','Progress','Closed','other');
8        output;
9      end;
10   end;
11   run;

NOTE: The data set WORK.ONE has 54995649 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           5.29 seconds
      cpu time            5.28 seconds


12
13   /* DOW loop approach */
14
15   data want1(drop=flag);
16   do until(last.type);
17     set one;
18     by type;
19     if mvalue='Progress' then flag=1;
20   end;
21   do until(last.type);
22     set one;
23     by type;
24     if flag then mvalue='Progress';
25     output;
26   end;
27   run;

NOTE: There were 54995649 observations read from the data set WORK.ONE.
NOTE: There were 54995649 observations read from the data set WORK.ONE.
NOTE: The data set WORK.WANT1 has 54995649 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           8.19 seconds
      cpu time            8.20 seconds


28
29   /* Self merge approach */
30
31   data want2(drop=_m);
32   merge one(rename=(mvalue=_m))
33         one(where=(mvalue='Progress') in=p);
34   by type;
35   if ~p then mvalue=_m;
36   run;

NOTE: MERGE statement has more than one data set with repeats of BY values.
NOTE: There were 54995649 observations read from the data set WORK.ONE.
NOTE: There were 13752908 observations read from the data set WORK.ONE.
      WHERE mvalue='Progress';
NOTE: The data set WORK.WANT2 has 54995649 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           9.83 seconds
      cpu time            9.82 seconds


37
38   /* PROC SQL approach */
39
40   proc sql;
41   create table want3 as
42   select type, case when max(mvalue='Progress')
43                  then 'Progress'
44                  else mvalue
45                end as mvalue
46   from one
47   group by type;
NOTE: The query requires remerging summary statistics back with the original data.
NOTE: SAS threaded sort was used.
NOTE: Table WORK.WANT3 created, with 54995649 rows and 2 columns.

48   quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           17.15 seconds
      cpu time            28.00 seconds&lt;/PRE&gt;
&lt;/LI-SPOILER&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 19 Jun 2019 14:17:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567292#M159514</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2019-06-19T14:17:48Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing values based on others rows value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567534#M159605</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32733"&gt;@FreelanceReinh&lt;/a&gt;&amp;nbsp;cool stuff &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;Here are my results on the large data. Just for fun I added a Hash Object approach&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data one(drop=i j);
length type $8 mvalue $12;
call streaminit(27182818);
do i=1 to 1e7;
  type=put(i, hex8.);
  do j=1 to rand('integer',10);
    mvalue=choosec(rand('integer',4),'closed','Progress','Closed','other');
    output;
  end;
end;
run; /* 54995649 obs. */

/* 10.72 sec */
data want1(drop=flag);
do until(last.type);
  set one;
  by type;
  if mvalue='Progress' then flag=1;
end;
do until(last.type);
  set one;
  by type;
  if flag then mvalue='Progress';
  output;
end;
run;

/* 11.8 sec */
data want2(drop=_m);
merge one(rename=(mvalue=_m))
      one(where=(mvalue='Progress') in=p);
by type;
if ~p then mvalue=_m;
run;

/* 37.3 sec */
proc sql;
create table want3 as
select type, case when max(mvalue='Progress')
               then 'Progress'
               else mvalue
             end as mvalue
from one
group by type;
quit;

/* 14.2 sec */
data want4;
   if _N_ = 1 then do;
      declare hash h(dataset:"one(where=(Mvalue='Progress'))", hashexp:20);
      h.defineKey('type');
      h.defineDone();
   end;

   set one;
   if h.check()=0 then Mvalue='Progress';
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 20 Jun 2019 05:52:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-values-based-on-others-rows-value/m-p/567534#M159605</guid>
      <dc:creator>PeterClemmensen</dc:creator>
      <dc:date>2019-06-20T05:52:50Z</dc:date>
    </item>
  </channel>
</rss>

