BookmarkSubscribeRSS Feed
🔒 This topic is locked. We are no longer accepting replies to this topic. Need further help? Please sign in and ask a new question.
SASJedi
SAS Super FREQ

The article SAS Tip: Sorting an Array in Descending Order - SAS Support Communities by @SAS_Tipster shows how to use call sortn (or call sortc) to sort an array in descending order, even though the call routines only support ascending order, using an array that lists the variables in reverse sequence. The example uses hard-coded variable names, which is great for a short list of variables. But what if you don't have a short list of conveniently named variables that is easy to type?

 

Article SAS Tip: Sorting an Array in Descending Order (extension) by @mkeintz shows how to use a hash object to sort the values and write them back into an array. With this technique, you don't need to write a variable list for the array variables. In the example, the HAVE data set has lots of variables (a--z), but you only want to reverse sort the values for g -- s in reverse order.

 

While I love the power and flexibility of DATA step hash objects, the hash object code is somewhat esoteric and complex. I propose a simpler technique:

Step 1: Use the PROC SQL dictionary.columns table to obtain a list of the desired column names in reverse order (by varnum) and store the list in a macro variable. Because only the metadata for the table is read by the PROC SQL step, the impact on performance is negligible. 

Step 2: Use a simple data step and a single array based on the macro variable list to reverse sort the values. 

 

Here's the code:

 

data have;
  input 
a b c d e f g h i j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z;
datalines;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
;

/* Get a list of the desired variables in reverse order by varnum into a macro variable */
proc sql noprint;
select Name
      into :revnames separated by ' '
      from dictionary.columns
   where libname ='WORK' and memname='HAVE'
	      and name between 'g' and 's'
	order by varnum desc
;
quit;
%put NOTE: &=revnames;

data want;
  set have;
  array revvals [*] &revnames;
  call sortn(of revvals[*]);
run;

 Results:

 

Have
Obs a b c d e f g h i j k l m n o p q r s t u v w x y z
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

 

Want

Obs a b c d e f g h i j k l m n o p q r s t u v w x y z
1 1 2 3 4 5 6 19 18 17 16 15 14 13 12 11 10 9 8 7 20 21 22 23 24 25 26
Check out my Jedi SAS Tricks for SAS Users

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


Register now!

Visit a random SAS tip This SAS Tips board is not open for replies or comments, but we welcome your feedback and questions. Have a question or comment about this tip? Start a new topic in one of our discussion boards, and reference this tip topic.
Discussion stats
  • 0 replies
  • 13459 views
  • 1 like
  • 1 in conversation