BookmarkSubscribeRSS Feed
GuiVtzl
Fluorite | Level 6

Hi, I have to do one calculation and I am completely stuck... Here is what I need :

I have two tables :

- table A : with row ID ID3

- table B : with row ID2

What I need to do is 20 iterations (that number is mandatory) that consist in :

iteration 1 : check for each line in B  if ID2 is in ID =>

                    if it is  then  (a new variable in B, let's call it NEW) NEW=ID3

                    if it is not then NEW=ID2

iteration 2 : check if NEW is in ID =>

                   if it is then NEW=ID3 (the "new" ID3, corresponding to the "new" ID)

                    if not then NEW=NEW

and so on until 20...

I really don't know how to do that. Could you help me please ? thanks a lot

Here's an exemple

Table A

ID                    ID3

25A                   35M

26B                    30C

30C                    23P

Table B 1st iteration

ID2                    NEW

25A                   35M

26B                    30C

Table B 2nd iteration

ID2                    NEW

25A                    35M

26B                    23P

and so on..

10 REPLIES 10
Tom
Super User Tom
Super User

Looks like table A represents changes to the ID values?  So 26B became 30C which became 23P.

Do you want to get to the final value?  Or do you want to include all of the intermediate values?

GuiVtzl
Fluorite | Level 6

Thanks Tom and RW9,

I have asked my boss, and it can be both !

in fact, table B can be both following ways :

     keep intermediate values

With a structure like

ID2 NEW_1 NEW_2 - ... - NEW_20 NEW_HIGH

where each NEW_i reflects the successive changes in ID2 and, in the end, NEW_HIGH would be equal to NEW_20 (We need it to be called NEW_HIGH for our work)

or

     without intermediate values

With a structure like

ID2 NEW_HIGH

where NEW_HIGH would be equivalent to the NEW_20 above

I really don't see how to do that. I thought about merges but I can't figure out how to keep ID which doesn't change at all in that case.

Do you see how to do that ? Both ways are ok (if you can, the simpliest one would be the best ahah)

Thanks a lot

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Hi,

I am struggling to follow your logic after the first iteration.  For iteration 1:

proc sql;

  create table FIRST as

  select  A.*

  from    TABLEA A

  right join TABLEB B

  on      A.ID=B.ID2;

quit;

Then after that you are probably better off creating a small macro:

%macro Do_your_logic (n=);

...

%mend Do_your_logic;

And calling it 20 times:

data _null_;

     do I=1 to 20;

          call execute('%Do_your_logic(n='||strip(put(I,best.))||');');

     end;

run;

Astounding
PROC Star

Simplest would be to convert Table A into a format (although a hash table would work reasonably well):

data table_A;

   set table_A;

   fmtname='$id';

   rename id=start id3=label;

run;

proc format cntlin=table_A;

run;

Next, use a DATA step to apply the format.  Perform one iteration to see if NEW actually changes, then perform the remaining 19 iterations if necessary:

data want;

   set table_B;

   new = put(id2, $id.);

   if new ne id2 then do _n_=1 to 19;

      new = put(new, $id.);

   end;

run;

You may need to learn about some of these tools, but at least the final program is relatively short and straightforward.  Good luck.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Or something like:

data tablea;
  attrib id id3 format=$5.;
  id="25A"; id3="35M"; output;
  id="26B"; id3="30C"; output;
  id="30C"; id3="23P"; output;
run;
data tableb;
  attrib id2 format=$5.;
  array new{20} $5.;
  id2="25A"; output;
  id2="26B"; output;
run;

data _null_;
  do i=1 to 20;
    if i=1 then do;
      call execute('proc sql;
                      update TABLEB
                      set NEW1=(select ID3 from TABLEA where TABLEB.ID2=TABLEA.ID);
                    quit;');
    end;
    else do;
      call execute('proc sql;
                      update TABLEB
                      set NEW'||strip(put(i,best.))||'=(select ID3 from TABLEA where TABLEB.NEW'||strip(put(i-1,best.))||'=TABLEA.ID);
                    quit;');
    end;
  end;
run;

GuiVtzl
Fluorite | Level 6

I would like to thank everyone here !
All of your answers have been very inspirational !

I applied the one provided by Astounding, and it worked just perfectly !

I have to say I have been quite amazed by that trick ! I called some of my colleagues to check on it and they were all "wooow".

Do you have any links or resources where I could learn more tools like that ?

Thanks a lot again, have a good day !

Astounding
PROC Star

GuiVtzl,

I think you already found the right place for ideas and techniques ... reading posts on this forum!

Patrick
Opal | Level 21

I have had a related problem in the past. Here what the Forum came up with

Tom
Super User Tom
Super User

One way is to convert your mapping table into a format.

Then in a data step loop testing the formatted value until you do not find any further recodes.

proc format ;

value $id

'25A'='35M'

'26B'='30C'

'30C'='23P'

other='   '

;

run;

data test;

  input id $ ;

  new=id;

  put id @ ;

  do while (put(new,$id.) ne ' ') ;

     new=put(new,$id.);

     put '-> ' new @;

  end;

  put;

cards;

25A

26B

run;


25A -> 35M

26B -> 30C -> 23P


Ksharp
Super User

If it was one point to one point , that would be easy. Let me know if it worked.

data a;
input ID      $              ID3 $;
cards;
25A                   35M
26B                    30C
30C                    23P
;
run;
data b;
input ID2 $ ;
cards;
25A 
26B 
;
run;
data want(keep=id2 new); 
 if _n_ eq 1 then do;
  if 0 then set a;
  declare hash ha(dataset:'a');
   ha.definekey('id');
   ha.definedata('id3');
   ha.definedone();
 end;
set b;
id=id2;     id3=' ';
do until(rc ne 0);
 rc=ha.find();id=id3;
end;
new=id3;
run;

Xia Keshan

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 10 replies
  • 1244 views
  • 0 likes
  • 6 in conversation