BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
ChrisHemedinger
Community Manager

Even so, I like the approach of the RANK function -- which we don't often see.  Converting the char to its ASCII value and comparing from there -- that's something that occurred to me too.  Nice one, @KachiM.

It's time to register for SAS Innovate! Join your SAS user peers in Las Vegas on April 16-19 2024.
hashman
Ammonite | Level 13

Chris,

 

Furthermore, RANK works almost 3 times faster than the 1. informat - and, interestingly, even about 2 times faster than the PIB1. informat, even though the results of rank(b) and input(b,pib1.) are exactly the same. By the way, the advantage of both is that they aren't limited to ASCII, and on an EBCDIC machine return the position of the character in the corresponding collating sequence. The same is true (only in reverse - from a collating sequence position to its character) for the BYTE function and PIB1. format.  

 

Paul D.

s_manoj
Quartz | Level 8
Hi @KachiM, liked your rank approach, can you please elaborate the use of "-48" over there?
hashman
Ammonite | Level 13

If you run the following on an ASCII machine:

data _null_ ;         
  do r = 48 to 57 ;   
    b = byte (r) ;    
    put r= b= ;
  end ;               
run ;                 

you'll see in the log:

r=48 b=0
r=49 b=1
r=50 b=2
r=51 b=3
r=52 b=4
r=53 b=5
r=54 b=6
r=55 b=7
r=56 b=8
r=57 b=9

In other words, in the ASCII collating sequence, the character "0" is in position (i.e. rank) 48, and the rest of the digits follow ascending. Hence, subtracting 48 from the rank maps the byte sequence "0123456789" from its ranks 48-57 to the integers 0-9, which is what the doctor ordered. 

 

However, one problem with hard coding -48 is, well, hard coding. This is because if datasp's code were executed on an EBCDIC machine (aka the mainframe), it would fail since in the EBCDIC collating sequence, the characters "0"-"9" occupy positions 240-249. Therefore, if datasp wanted the code to be portable (aka machine-independent), it would have to be coded rather in this vein:

data _null_ ;                     
  c = '000112010302' ;            
  max = 0 ;                       
  r0 = rank ("0") ;               
  do i = 1 to length(c) ;         
    x = rank (char (c, i)) - r0 ;
    max = max <> x ;             
  end ;                           
  put max= ;                      
run ;                             

This way, it would execute with the expected result regardless of the encoding used on the machine where the code is run.

 

Paul D.

s_manoj
Quartz | Level 8
Thank you very much, it's very informative

MarkWik
Quartz | Level 8

Everyone who contributed  to the thread has been fantastic and I wish I had the ability to code or let alone think at that level.

 

How long have you(to each one of you who contributed) been using SAS to be so competent?

FreelanceReinh
Jade | Level 19

@MarkWik wrote:

Everyone who contributed  to the thread has been fantastic and I wish I had the ability to code or let alone think at that level.

 

How long have you(to each one of you who contributed) been using SAS to be so competent?


Thanks, @MarkWik,

 

I've been using SAS for 20 years (started with version 6.12). FINDC and similarly adjustable functions were only introduced in SAS 9, though.

hashman
Ammonite | Level 13

FreelanceReinhard,

 

While it's true that the FIND family was unveiled in version 9.0, the idea you offered here could be also implemented using INDEXC which had been available earlier - definitely since version 8 (though I suspect even since version 7).

 

Best

Paul D.   

FreelanceReinh
Jade | Level 19

Oh yes, you're right: Tom's version of the solution could use INDEXC in lieu of FINDC:

h=10-indexc('9876543210 ',c);

INDEXC was already available in SAS 6.12.

art297
Opal | Level 21

@FreelanceReinh and @hashman Since indexc does the same thing, runs 36% faster than findc, and shorter function names don't count in this game, here is my revised entry:

 

dat have;
  inpu k $12.;
  card;
000112010302
0
1
2
3
4
5
6
7
8
9
0123456987
.
;

dat w;
  se;
  h=10-indexc('9876543210 ',k);
ru;

Art, CEO, AnalystFinder.com

 

hashman
Ammonite | Level 13

Correct. I failed to rack my brain far enough back in time.

novinosrin
Tourmaline | Level 20

@MarkWikNot sure If i belong to the competent list, but have been user since Oct 2013, getting to 5 years+ 1 year prior to that of getting to know what is sas like a generic exposure. So yeah, a long way to go to catch up with 20,30 plusses in the list

s_manoj
Quartz | Level 8

wow such a great post, I have learned very much unique approaches from this post, THANK YOU all contributors

tc
Lapis Lazuli | Level 10 tc
Lapis Lazuli | Level 10

How about some "job  security" solutions? Man Happy

 

Hole-In-Three

proc format;
picture separate low-high='9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9';
%put MaxDigit: %sysfunc(max(%sysfunc(putn(%sysfunc(inputn(%sysfunc(compress("000112010302",'"')),16.)),separate.))));

 

Way-Over-Par (Recursion)

%macro maxdigit(digits,d);
%if &d= %then %let d=%length(&digits);
%if &d<=1 %then %substr(&digits,&d,1);
%else %sysfunc(max(%substr(&digits,&d,1),%maxdigit(&digits,%eval(&d-1))));
%mend;
%put MaxDigit: %maxdigit(000112010302);
RobPratt
SAS Super FREQ
proc optmodel;
   str s = '000112010302';
   put(max {k in 1..length(s)} char(s,k));
quit;

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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