DATA Step, Macro, Functions and more

Dynamic Hash Definition

Accepted Solution Solved
Reply
New Contributor
Posts: 2
Accepted Solution

Dynamic Hash Definition

Hi,

Is there any way to create a hash table from a dataset, where the dataset name is provided dynamically during the data step?  I am trying to create a macro variable to store a dataset name, and then use that name to create a hash table. However, it fails because the hash definition is compiled before runtime while the macro variable values are not assigned until runtime. Is there any way to fix the timing?

This is what I am trying to do. Thanks for any advice:

DATA scratch.taq2;

format date yymmddn8. txtdate $8. symbol $10. time TIME8.;

set taq1;

declare hash wcthash;

if ('10:00't le acttims < '15:30't) then do;

  *need date as text to use as title of dataset;

  txtdate=PUT(actdats, yymmddn8.);

  call symput('yymmdd',txtdate);

  call symput('symb',symbol);

  date= actdats;

  time= INTNX('minutes',acttims,-15);

  price =.;

  %put 'date is ' &yymmdd;

  %put 'Symbol is ' &symb;

  wcthash = _new_ hash(dataset: "wtaq.WCT_&yymmdd (where=(symbol='&symb'))", multidata:'yes');

  wcthash.DefineKey("date","time");

  wcthash.DefineData("date","time","price");

  wcthash.DefineDone();

  do while (time < acttims);

  rc=wcthash.find();

  if rc=0 then output;

  if rc=0 then time = acttims;

  else time = INTNX('second',time,1);

  end;

  rc = wcthash.delete();

end;

RUN;


Accepted Solutions
Solution
‎04-15-2015 11:40 AM
Trusted Advisor
Posts: 1,300

Re: Dynamic Hash Definition

The hash definition variables accept scalar arguments,so using the macro variables is unnecessary.

proc sql;

create table class_sex as select distinct sex from sashelp.class;

create table class_m as select * from sashelp.class where sex='M';

create table class_f as select * from sashelp.class where sex='F';

quit;

data _null_;

if 0 then set sashelp.class;

declare hash myhash;

set class_sex;

dsn = cats('work.class_', sex, '(where=(sex=''', sex, '''))');

myhash = _new_ hash(dataset:dsn);

myhash.definekey('name');

myhash.definedata('name', 'weight', 'height');

myhash.definedone();

myhash.output(dataset:'class_hash');

stop;

run;

View solution in original post


All Replies
Valued Guide
Posts: 3,208

Re: Dynamic Hash Definition

What is your goal? Normally a hash is create only once and than de datastep does an iteration on a dataset using a PDV.

It doesn't make sense avoiding that. The HASH itself is defined using string that may be variabels as used in the datastep. SAS(R) 9.3 Component Objects: Referencehttp://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002576871.htm
Having the string as a variable should solve that. But the hash is vanished after a datastep. What are you up to? 

---->-- ja karman --<-----
Solution
‎04-15-2015 11:40 AM
Trusted Advisor
Posts: 1,300

Re: Dynamic Hash Definition

The hash definition variables accept scalar arguments,so using the macro variables is unnecessary.

proc sql;

create table class_sex as select distinct sex from sashelp.class;

create table class_m as select * from sashelp.class where sex='M';

create table class_f as select * from sashelp.class where sex='F';

quit;

data _null_;

if 0 then set sashelp.class;

declare hash myhash;

set class_sex;

dsn = cats('work.class_', sex, '(where=(sex=''', sex, '''))');

myhash = _new_ hash(dataset:dsn);

myhash.definekey('name');

myhash.definedata('name', 'weight', 'height');

myhash.definedone();

myhash.output(dataset:'class_hash');

stop;

run;

New Contributor
Posts: 2

Re: Dynamic Hash Definition

yes, this is great. Thank you! Thanks both of you, you were both correct. I don't know why I was making it more complicated than it needed to be.  It works very well now:

449

450  DATA scratch.taq2;

451  format date yymmddn8. txtdate $8. symbol $10. time TIME8.;

452  set taq1;

453

454  declare hash wcthash;

455

456  if ('10:00't le acttims < '15:30't) then do;

457      *need date as text to use as title of dataset;

458      txtdate=PUT(actdats, yymmddn8.);

459

460

461      date= actdats;

462      time= INTNX('minutes',acttims,-15);

463      price =.;

464

465

466      mystring = 'wtaq.WCT_'||txtdate||' (where=(symbol='''||symbol||'''))';

467

468      wcthash = _new_ hash(dataset: mystring, multidata:'yes');

469      wcthash.DefineKey("date","time");

470      wcthash.DefineData("date","time","price");

471      wcthash.DefineDone();

472

473

474      do while (time < acttims);

475          rc=wcthash.find();

476          if rc=0 then output;

477          if rc=0 then time = acttims;

478          else time = INTNX('second',time,1);

479      end;

480

481      rc = wcthash.delete();

482  end;

483  RUN;

NOTE: There were 7790 observations read from the data set WTAQ.WCT_20030520.

      WHERE symbol='IBM       ';

NOTE: There were 10457 observations read from the data set WTAQ.WCT_20050720.

      WHERE symbol='IBM       ';

NOTE: There were 9011 observations read from the data set WTAQ.WCT_20060403.

      WHERE symbol='IBM       ';

NOTE: There were 10400 observations read from the data set WTAQ.WCT_20060421.

      WHERE symbol='IBM       ';

NOTE: There were 35566 observations read from the data set WTAQ.WCT_20080421.

      WHERE symbol='IBM       ';

NOTE: There were 56548 observations read from the data set WTAQ.WCT_20090720.

      WHERE symbol='IBM       ';

NOTE: There were 2520 observations read from the data set WTAQ.WCT_20031224.

      WHERE symbol='IBM       ';

NOTE: There were 8958 observations read from the data set WTAQ.WCT_20050615.

      WHERE symbol='IBM       ';

NOTE: There were 16688 observations read from the data set WTAQ.WCT_20060419.

      WHERE symbol='IBM       ';

NOTE: There were 9721 observations read from the data set WTAQ.WCT_20050506.

      WHERE symbol='IBM       ';

NOTE: There were 10 observations read from the data set WORK.TAQ1.

NOTE: The data set SCRATCH.TAQ2 has 10 observations and 11 variables.

NOTE: DATA statement used (Total process time):

      real time           3.07 seconds

      cpu time            0.16 seconds

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 3 replies
  • 269 views
  • 1 like
  • 3 in conversation