Date: Tue, 15 Apr 2008 14:54:56 -0400
Reply-To: Chang Chung <chang_y_chung@HOTMAIL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Chang Chung <chang_y_chung@HOTMAIL.COM>
Subject: Re: need help in coding this...
On Tue, 15 Apr 2008 06:24:02 -0400, Mark Marquez <sickpurple@GMAIL.COM> wrote:
>hi, i have a problem in coding the following scenario...
>
>Given the following data set w/ 5 obs (the # of iterations will be equal to
>the # of obs):
>f1, f2
>1, 4
>1, 3
>2, 2
>4, 4
>4, 5
>
>1st iteration--point to obs 1 (f1=1, f2=4); get the minimum between f1 & f2
>(min=1) for the current obs; update starting from the current obs (obs 1)
>until the last obs for all occurrences of the higher value between f1 & f2
>(4) set equal to the minimum (1)
>f1, f2
>1, 4-->1
>1, 3
>2, 2
>4-->1, 4-->1
>4-->1, 5
>
>2nd iteration--point to obs 2 (f1=1, f2=3); get the minimum between f1 & f2
>(min=1) for the current obs; update starting from the current obs (obs 2)
>until the last obs for all occurrences of the higher value between f1 & f2
>(3) set equal to the minimum (1)
>f1, f2
>1, 1
>1, 3-->1
>2, 2
>1, 1
>1, 5
>
>3rd iteration--point to obs 3 (f1=2, f2=2); skip; no update needed since
>both are equal
>f1, f2
>1, 1
>1, 1
>2, 2
>1, 1
>1, 5
>
>4th iteration--point to obs 4 (f1=1, f2=1); skip; no update needed since
>both are equal
>f1, f2
>1, 1
>1, 1
>2, 2
>1, 1
>1, 5
>
>5th & last iteration--point to obs 5 (f1=1, f2=5); get the minimum between
>f1 & f2 (min=1) for the current obs; update the current obs (obs 5) for the
>occurrence of the higher value between f1 & f2 (5) set equal to the minimum (1)
>f1, f2
>1, 1
>1, 1
>2, 2
>1, 1
>1, 5-->1
>
>Final data set--yes, both f1 & f2 will end up having the same values:
>f1, f2
>1, 1
>1, 1
>2, 2
>1, 1
>1, 1
hi, Mark,
here is single data step implementation. Notice that it updates the input
data in-place. If you don't want to replace the input dataset, then make a
backup first. hth.
cheers,
chang
p.s. this implementation still reads the data a lot. In fact, given the
number of observation, n, at maximum, it can read 1 + 2 + ... + (n-1) + n
observations, reading the first observation once,..., and the last
observation n times. I think it is possible to write a single data step to
read each observation only once but get this done. anybody wants to try?
/* test data */
data one;
input f1 f2;
cards;
1 4
1 3
2 2
4 4
4 5
;
run;
/* using set with point= option */
data one;
do p1 = 1 to n;
p = p1;
link modify;
/* find min and max */
if f1=f2 then
continue;
else if f1<f2 then do;
minf = f1; maxf = f2;
end; else do;
minf = f2; maxf = f1;
end;
/* replace */
p2 = p1;
do while (p2<=n);
f1 = ifn(f1=maxf, minf, f1);
f2 = ifn(f2=maxf, minf, f2);
replace;
p2 + 1;
if p2>n then continue;
p = p2;
link modify;
end;
end;
stop;
modify:
modify one point=p nobs=n;
return;
run;
/* check */
proc print data=one;
run;
/* on lst
Obs f1 f2
1 1 1
2 1 1
3 2 2
4 1 1
5 1 1
*/
|