DATA Step, Macro, Functions and more

Hash object's replace method doesn't seem to be working.

Reply
Occasional Contributor
Posts: 7

Hash object's replace method doesn't seem to be working.

Hello Everyone,

In the code below, the replace method isn't doing what it should be doing. In fact, when I take that statement out of the code it returns the same results. Can someone please look at this and help me out? Thanks.

Note: there are no errors of any kind returned.

data final;

  if 0 then set mbr prov;

  declare hash h_prov (dataset: 'prov');

  declare hiter i_prov ('h_prov');

  h_prov.definekey (all: 'yes');

  h_prov.definedata (all: 'yes');

  h_prov.definedone();

  do until (eof);

  set mbr end = eof;

  rc = i_prov.first();

  do while (rc = 0);

  if mbr_ped_ind eq 'Y' then

  do;

  if prov_ped_ind eq 'Y' and members lt &capacity then

  do;

  gdist = geodist(mbr_lat, mbr_lon, prov_lat, prov_lon, 'M');

  if gdist le &dist_limit1 then

  do;

  members + 1;

  h_prov.replace();

  mbr_id = dw_mbr_key;

  pcp_id = npi_id;

  output;

  leave;

  end;

  else if gdist le &dist_limit2 then

  do;

  members + 1;

  h_prov.replace();

  mbr_id = dw_mbr_key;

  pcp_id = npi_id;

  output;

  leave;

  end;

  else if gdist le &dist_limit3 then

  do;

  members + 1;

  h_prov.replace();

  mbr_id = dw_mbr_key;

  pcp_id = npi_id;

  output;

  leave;

  end;

  end;

  end;

run;

Super User
Posts: 10,548

Re: Hash object's replace method doesn't seem to be working.

You should provide some example data, both of the Hash set and your input and what the desired output should be.

Very hard to determine what problems may be data related without data...

And values for the macro variables.

When you ran this code did you get any errors? I think there is a missing END; in there somewhere.

PROC Star
Posts: 1,236

Re: Hash object's replace method doesn't seem to be working.

Yes, please post more of the sample data.  I would actually go back to this thread, assume this is what you are trying to solve?  https://communities.sas.com/thread/86402  Or move more of that background information here.   Now that you have @ballardw's attention you'll have better luck than when it was just me. : )

Assuming MEMBERS is in the PROV dataset, I don't think you want it to be part of the key for h_prov.   Because when you update it in the DATA step and then use REPLACE(), it won't find the matching record.

I think the key for h_prov should be pcp_id. I'm assuming h_prov is your hash of the dataset of libraries (providers in real life? : ) .   Instead, just read one member from MBR.  Then iterate over every record in h_prov, checking to find the provider that is closest to them and has capacity.  After iterating over through the entire hash table, you will know which provider to assign that member to.  So assign the member.  Then update the hash table record for that provider, decrementing by 1.

Occasional Contributor
Posts: 7

Re: Hash object's replace method doesn't seem to be working.

WOW. That fixed it. I only had to change the key to prov_id. Thanks very much. I really appreciate this.

PROC Star
Posts: 1,236

Re: Hash object's replace method doesn't seem to be working.

No problem.  I haven't done much with hash but took a shot at my understanding of what you want (no worrying about optimization).  Could be mistakes, and would want to add error handling.  But figured I'd share in case its of interest.

data members;
  input member_id member_zip;
  cards;
1 02138
2 02138
3 02139
4 02139
5 02860
6 02806
;

data providers;
  input pcp_id provider_zip capacity;
  cards;
15 02139 1
18 02139 2
21 02806 20
;
run;

data want(keep=member_id member_zip pcp_id provider_zip distance);
  if 0 then set providers;
  set members end=last;
  if _N_ = 1 then do;  
   
declare hash h(dataset:'providers', duplicate:"error");
    h.defineKey('pcp_id');    
    h.defineData(ALL:
"YES");
    h.defineDone();
   
declare hiter hiter ("h" ) ;
  end;

  rc=hiter.first();
 
do while(rc=0);
    if capacity>0 then do;
      distance=zipcitydistance(member_zip,provider_zip);
     
if .Z<distance<mindistance or missing(mindistance) then do;
        MinDistance=Distance;
        SelectedPCP_ID=pcp_ID;
     
end;
   
end;
    rc=hiter.next();
 
end;
 
*now we have iterated over all providers, and selected closest one;
 
*need to decrement the capacity in the hash table;
  PCP_ID=SelectedPCP_ID;
  h.find();
  capacity=capacity-
1;
  h.replace();

 
*output dataset of how much capacity remains at each provider;
 
if last then h.output (dataset: "Providers2") ;
run;

Ask a Question
Discussion stats
  • 4 replies
  • 224 views
  • 0 likes
  • 3 in conversation