BookmarkSubscribeRSS Feed
Mushy
Quartz | Level 8

Hello,

 

Do we have an equivalent hash code for :

 

proc sort data=test;by id descending sub;
run;

 

I would like to see how we could define multiple keys ordered mixed. 

 

Thanks,

Mushy

3 REPLIES 3
PeterClemmensen
Tourmaline | Level 20

No unfortunately it's not possible. For multiple keys, they will either be all sorted ascending - or descending when you use the Ordered : Argument Tag.

mkeintz
PROC Star

There's no direct analog to "by x y descending z" in hash object storage.  

 

But you can replicate it by use of hash-of-hashes.  Here's a made-up example that replicates BY MAKE DESCENDING WEIGHT for sashelp.cars:

 

proc sort data=sashelp.cars out=cars;
  by descending make;
run;

data want (drop=_:);
  if 0 then set cars;
  declare hash h ;
  declare hiter hi ;
  declare hash hoh (ordered:'A');
    hoh.definekey('make');
    hoh.definedata('make','h','hi');
    hoh.definedone();
  declare hiter hohi ('hoh');


  do until (end_of_cars);
    set cars end=end_of_cars;
    if hoh.find() ^=0 then do;
      h=_new_ hash(dataset:'cars (obs=0)',ordered:'D',multidata:'Y');
      h.definekey('weight');
      h.definedata(all:'Y');
      h.definedone();
      hi=_new_ hiter('h');
      hoh.add();
    end;
    h.add();
  end;

  do _i=hohi.first() by 0 until (hohi.next()^=0);
    do _j=hi.first() by 0 until (hi.next()^=0);
      output;
    end;
  end;
run;

In the location of the "OUTPUT" statement is where you might also do programming that depends on the reordered sequence.  For instance if you wanted change of weight from one obs to the next:

 

  call missing(of _all_);
  do _i=hohi.first() by 0 until (hohi.next()^=0);
    do _j=hi.first() by 0 until (hi.next()^=0);
      weight_change=dif(weight);
      if make^=lag(make) then weight_change=.;
      output;
    end;
  end;

I preceded this with the CALL MISSING(of _ALL_), which wasn't essential in this particular example, but is a good idea for properly replicating reading the first record in a SET .... BY MAKE DESCENDING WEIGHT.

 

This could be definitely by greatly simplified by a sas implementation of something like "ORDERED:(MAKE descending WEIGHT)" - there would be no need for coding a hash-of-hashes solution.

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
FreelanceReinh
Jade | Level 19

Hello @Mushy,

 

Alternatively you can create one or more replacement keys whose sort order reverses the sort order of the corresponding original keys. For example, use -sub for a numeric variable sub or

-input(put(sub,$hex6.),hex6.)

 for a character variable sub of length 3. (For character variables of arbitrary lengths you could replace each character c by byte(255-rank(c)).)

 

Example using mkeintz's dataset CARS:

proc sql noprint;
select quote(trim(name)) into :varlist separated by ','
from dictionary.columns
where libname='WORK' & memname='CARS';
quit;

data _null_;
if _n_=1 then do;
  dcl hash h(ordered:'a', multidata:'y');
  h.definekey('make','_w');
  h.definedata(&varlist);
  h.definedone();
end;
set cars end=last;
_w=-weight;
h.add();
if last then h.output(dataset:'want');
run;

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 3 replies
  • 1005 views
  • 6 likes
  • 4 in conversation