BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
mikersas
Obsidian | Level 7

New to Hash Tables.  Trying to tally mutilple fields in a table that are in error. I'm not getting there.. This is the code:

 

Data _null_;
format DATA_name $32.;
format counter_save 8.;
If _N_ = 1 then do;

declare Hash FieldCounters(HashExp:8, multidata: 'YES');
rc = FieldCounters.DefineKey ('DATA_name');
rc = FieldCounters.DefineData ('DATA_name','counter');
rc = FieldCounters.DefineDone ();
declare hiter hifc("FieldCounters");
call missing(DATA_name);

do until (eof1);
set work.DEFAULTVALUESHASH end= eof1;
rc = FieldCounters.add();
end;

end;
set targt.OD001(keep=ENTITY_CRE_FLG ERROR_HOLD) end=end1;

If ENTITY_CRE_FLG ne 'Y' then do;
DATA_name = 'ENTITY_CRE_FLG';
rc = FieldCounters.find(key:'DATA_name');
counter_save = counter + 1;
counter = counter_save;
rc = FieldCounters.replace();
end;
If missing(ERROR_HOLD) = 0 then do;
DATA_name = 'ERROR_HOLD';
rc = FieldCounters.find(key:'DATA_name');
counter_save = counter + 1;
counter = counter_save;
rc = FieldCounters.replace();
end;

if end1 then do;
put '######### Got here';
rc=FieldCounters.output(dataset: 'work.hashout');
end;

run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
mikersas
Obsidian | Level 7

Actually, I'm getting double counting in the relevant hash rows.  I'm attaching the code, log, hash table input, hash table output and input data.

View solution in original post

4 REPLIES 4
Quentin
Super User
Suggest you include a small amount of sample data and the desired output, and also describe what happens when you run your code (getting errors in the log or just getting the wrong result, how is it wrong, etc.)
The Boston Area SAS Users Group is hosting free webinars!
Next up: Bart Jablonski and I present 53 (+3) ways to do a table lookup on Wednesday Sep 18.
Register now at https://www.basug.org/events.
mikersas
Obsidian | Level 7

Actually, I'm getting double counting in the relevant hash rows.  I'm attaching the code, log, hash table input, hash table output and input data.

Patrick
Opal | Level 21

"I'm attaching the code, log, hash table input, hash table output and input data"

 

I can't find all this information in your attachment. Anyway: If you are just after a simple count then below should work.

Run the code and let us know if this returns the result you're after.

 

 

libname targt (work);
data targt.OD001;
  input ENTITY_CRE_FLG :$1. ERROR_HOLD @@;
  output;
  datalines;
Y 1 N 1 N . N 5 Y 5 Y . 
  ;
run;

Data _null_;
  length DATA_name $32.;

  If _N_ = 1 then
    do;
      declare Hash FieldCounters(HashExp:4, multidata: 'NO');
      rc = FieldCounters.DefineKey ('DATA_name');
      rc = FieldCounters.DefineData ('DATA_name','counter');
      rc = FieldCounters.DefineDone ();
      call missing(DATA_name);
    end;

  set targt.OD001(keep=ENTITY_CRE_FLG ERROR_HOLD) end=end1;

  If ENTITY_CRE_FLG ne 'Y' then
    do;
      DATA_name = 'ENTITY_CRE_FLG';
      rc = FieldCounters.find();
      counter=sum(counter,1);
      rc = FieldCounters.replace();
    end;

  If missing(ERROR_HOLD) = 0 then
    do;
      DATA_name = 'ERROR_HOLD';
      rc = FieldCounters.find();
      counter=sum(counter,1);
      rc = FieldCounters.replace();
    end;

  if end1 then
    do;
      put '######### Got here';
      rc=FieldCounters.output(dataset:'work.hashout');
    end;
run;

 

In case you want to pre-populate your hash with a list of expected values with a counter initiated to 0 then below code should do.

libname targt (work);
data targt.OD001;
  input ENTITY_CRE_FLG :$1. ERROR_HOLD @@;
  output;
  datalines;
Y 1 N 1 N . N 5 Y 5 Y . 
  ;
run;

data work.DEFAULTVALUESHASH;
  length DATA_name $32.;
  counter=0;
  DATA_name='ENTITY_CRE_FLG';
  output;
  DATA_name='ERROR_HOLD';
  output;
  DATA_name='SOMETHING ELSE';
  output;
run;

Data _null_;
  If _N_ = 1 then
    do;
      if 0 then set work.DEFAULTVALUESHASH;
      declare Hash FieldCounters(dataset:'work.DEFAULTVALUESHASH');
      rc = FieldCounters.DefineKey ('DATA_name');
      rc = FieldCounters.DefineData (all:'y');
      rc = FieldCounters.DefineDone ();
      call missing(of _all_);
    end;

  set targt.OD001(keep=ENTITY_CRE_FLG ERROR_HOLD) end=end1;

  If ENTITY_CRE_FLG ne 'Y' then
    do;
      DATA_name = 'ENTITY_CRE_FLG';
      rc = FieldCounters.find();
      counter=sum(counter,1);
      rc = FieldCounters.replace();
    end;

  If missing(ERROR_HOLD) = 0 then
    do;
      DATA_name = 'ERROR_HOLD';
      rc = FieldCounters.find();
      counter=sum(counter,1);
      rc = FieldCounters.replace();
    end;

  if end1 then
    do;
      put '######### Got here';
      rc=FieldCounters.output(dataset:'work.hashout');
    end;
run;

 

slchen
Lapis Lazuli | Level 10

Without example data,the desired output and log information, it is hard to give good suggestions. Just from codes, there are keys in your definekey, but only one key was used, and key was quoted by single quote, correct use is FieldCounters.find(key: DATA_name,key: counter), or just FieldCounters.find() if key variables were the same; In addition, with rc = FieldCounters.find(), if then condition should be used.

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 4 replies
  • 1590 views
  • 0 likes
  • 4 in conversation