BookmarkSubscribeRSS Feed
gyambqt
Obsidian | Level 7

Hello Experts,

When I create a hash table, I have to specify the key value, but if I want to replace the key value with a new variable created during the hash iterator process within the same data step. How do I do that?

For the code below, I want the dataset work.temp1(highlighted in red) to be created  before it hold by "mylittlehash1" ,how do I achieve that?

My goal is to use one single datastep (with hash) to complete the task as shown in the code below.


data work.temp1 work.temp2;
attrib filename length=$1000
sfname length=$1000
key length=$1000;
if _n_=1 then do;
declare hash mylittlehash(dataset: 'library.want', ordered:'yes');
declare hiter mylittlehashter('mylittlehash');
mylittlehash.defineData('filename');
mylittlehash.defineKey('sfname');
mylittlehash.defineDone();
call missing(filename,sfname,key);

rc=mylittlehashter.first();
do until (rc ne 0);
perlexpression2=prxparse("/\w*(\w\w\d\d\d\d)(\w)\w*/");
if prxmatch(perlexpression2,filename) then do;
Key=upcase((prxposn(perlexpression2,1,filename)));
output work.temp1;
rc=mylittlehashter.next();
end;
end;
declare hash mylittlehash1(dataset: 'work.temp1', ordered:'yes', duplicate: 'r');
mylittlehash1.defineKey('key');
mylittlehash1.defineData('key');
mylittlehash1.defineDone();
end;
set files_found;
perlexpression=prxparse("/\w*(\w\w\d\d\d\d)(\w)\w*/");
if prxmatch(perlexpression,filename) then do;
Key=upcase((prxposn(perlexpression,1,filename)));
end;
if prxposn(perlexpression,2,filename)="Z";
rc=mylittlehash1.check();

if rc=0 then output work.temp2;
run;

Thanks

5 REPLIES 5
Patrick
Opal | Level 21

Declare 2 hashes together within the "if _n_=1, then within your hiter loop instead of writing to "output work.temp1" you add the records to the 2nd hash "myhash2.add()".

Once you finished iteration through the first hash you can delete it if you want "mylittlehash1.delete()", and should you also need "work.temp1" after the data step finished then write your 2nd hash to a table "myhash2.output(dataset:"work.temp1")

gyambqt
Obsidian | Level 7


Hi Patrick,

I have modified the code like below:

Is that correct?

data work.temp;

attrib filename length=$1000

sfname length=$1000

key length=$1000;

if _n_=1 then do;

declare hash mylittlehash(dataset: 'library.want(where =(_job_status="Failed"))', ordered:'yes');

declare hiter mylittlehashter('mylittlehash');

mylittlehash.defineData('filename');

mylittlehash.defineKey('sfname');

mylittlehash.defineDone();

call missing(filename,sfname,key);

declare hash mylittlehash1();

mylittlehash1.defineKey('key');

mylittlehash1.defineData('key');

mylittlehash1.defineDone();

rc=mylittlehashter.first();

do until (rc ne 0);

perlexpression2=prxparse("/\w*(\w\w\d\d\d\d)(\w)\w*/");

if prxmatch(perlexpression2,filename) then do;

Key=upcase((prxposn(perlexpression2,1,filename)));

r=mylittlehash1.add();

rc=mylittlehashter.next();

end;

end;

end;

set files_found;

perlexpression=prxparse("/\w*(\w\w\d\d\d\d)(\w)\w*/");

if prxmatch(perlexpression,filename) then do;

Key=upcase((prxposn(perlexpression,1,filename)));

end;

if prxposn(perlexpression,2,filename)="Z";

rc=mylittlehash1.check();

if rc=0 then output work.temp;

run;

Patrick
Opal | Level 21

Without sample data I can't check if this works in full detail - but from what I can see the code looks pretty good. I've made a few changes to your code. I've added comments where the changes were actually important and not just cosmetic.

data work.temp;

  attrib filename length=$1000

    sfname length=$1000

    key length=$1000;

  if _n_=1 then

    do;

      declare hash mylittlehash(dataset: 'library.want(where =(_job_status="Failed"))', ordered:'yes');

      declare hiter mylittlehashter('mylittlehash');

      rc=mylittlehash.defineData('filename');

      rc=mylittlehash.defineKey('sfname');

      rc=mylittlehash.defineDone();

      declare hash mylittlehash1();

      rc=mylittlehash1.defineKey('key');

      rc=mylittlehash1.defineData('key');

      rc=mylittlehash1.defineDone();

      call missing(of _all_);

      rc=mylittlehashter.first();

      /* keep prxparse outside of the loop or the expression will get compiled */

      /* for every single iteration of the loop (slow and cluttering memory)   */

      perlexpression2=prxparse("/\w*(\w\w\d\d\d\d)(\w)\w*/");

      do until (rc ne 0);

        if prxmatch(perlexpression2,filename) then

          do;

            Key=upcase((prxposn(perlexpression2,1,filename)));

            r=mylittlehash1.add();

            rc=mylittlehashter.next();

          end;

      end;

    end;

  set files_found;

  /* same thing: compile the expression only once */

  retain perlexpression;

  if _n_=1 then

    perlexpression=prxparse("/\w*(\w\w\d\d\d\d)(\w)\w*/");

  if prxmatch(perlexpression,filename) then

    do;

      Key=upcase((prxposn(perlexpression,1,filename)));

    end;

  if prxposn(perlexpression,2,filename)="Z" then

    do;

      if mylittlehash1.check() = 0 then

        output work.temp;

    end;

run;

gyambqt
Obsidian | Level 7

Thanks a lot!

Patrick
Opal | Level 21

Did this answer your question? If so then please mark the answer as correct.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 5 replies
  • 913 views
  • 0 likes
  • 2 in conversation