Statistical programming, matrix languages, and more

Find the ASCII code of a character in IML

Reply
Frequent Contributor
Posts: 143

Find the ASCII code of a character in IML

This should be simple, but I just can't see it.

What is the best way to replicate the functionality of the data-step RANK function from within IML?

Using syntax such as rank('G') results in the error, "Character operation not implemented yet", which I presume is referring to the IML RANK function not being able to handle a character matrix.

Thanks,

Ian.

Super Contributor
Posts: 297

Re: Find the ASCII code of a character in IML

Hi Ian,

You  might find the following link interesting.

SAS/IML(R) 9.22 User's Guide

Specifically the section referring to the following code.

/* Create RANK-like functionality for character matrices */

start rankc(x);

  s = unique(x); /* the unique function returns a sorted list */

  idx = j(nrow(x), ncol(x));

  ctr = 1; /* there can be duplicate values in x */

  do i = 1 to ncol(s); /* for each unique value */

  t = loc(x = s);

  nDups = ncol(t);

  idx = ctr : ctr+nDups-1;

  ctr = ctr + nDups;

  end;

  return (idx);

finish;

/* call the RANKC module */

x = {every good boy does fine and good and well every day};

rc = rankc(x);

print rc[colnam=x];

/* Notice that ranking is in ASCII order, in which capital

  letters precede lower case letters. To get case-insensitive

  behavior, transform the matrix before comparison */

x = {"a" "b" "X" "Y" };

asciiOrder = rankc(x);

alphaOrder = rankc(upcase(x));

print x, asciiOrder, alphaOrder;

Frequent Contributor
Posts: 143

Re: Find the ASCII code of a character in IML

Hi Scott,

Thanks, but I am not looking to get the rank order of all the elements in a character matrix.  In a data-step rank('G') returns  71, the character code for the letter G, I am looking for the equivalent of that in IML.

SAS Super FREQ
Posts: 3,624

Re: Find the ASCII code of a character in IML

You title suggests that you want to find the ascii code. Try this:

ascii = byte(65:122);

label = "A65":"A122";

print ascii[colname=label];

Frequent Contributor
Posts: 143

Re: Find the ASCII code of a character in IML

Thanks Rick,

I have gone with

start char_rank(c);

  ascii = byte(65:122);

  return( loc( ascii = c) + 64);

finish;

it will work for what I have in mind as I know c will always be a single letter.  I was kind of hoping that since BYTE was available, then there should be a way to get the inverse function.

Ian.

SAS Super FREQ
Posts: 3,624

Re: Find the ASCII code of a character in IML

Sounds good. Here's a cute idea that falls into the "isn't that interesting" category. It maps each alphabetical value (no punctuation) to the ascii code for the uppercase version of the letter:

asciiVals = 65:90;

letters = byte(asciiVals);

mattrib asciiVals colname=letters;

str = {I A N W A K E L I N G};

b = asciiVals[,str];

print b;

Probably not useful for your application, but fun. For more on the MATTRIB function, see Access rows or columns of a matrix by names - The DO Loop

Frequent Contributor
Posts: 143

Re: Find the ASCII code of a character in IML

That's a very nice and a unintended use of mattrib.  Unfortunately my application has lower case letters as well otherwise I would use it.

The character data that I want to convert comes in blocks of letters without delimiters and I find that I need to chop the blocks into individual characters as you have done with my name above.   There is no need to loop over each character in the string, as I have found that I can do this as follows:

start chop(s);
  call execute( cat( 'chopstr = {', prxchange( "s/(.)/'$1' /", -1, s), '};') );
  return(chopstr);
finish;

str=chop('IanWakeling');
print str;

By the way, it is not possible to use a call execute to return from a function module - I tried!

SAS Super FREQ
Posts: 3,624

Re: Find the ASCII code of a character in IML

If you have SAS/IML 12.1, you can use a new feature of the SUBSTR function:

start chop(s);

  return ( substr(s, 1:nleng(s), 1) );

finish;

Frequent Contributor
Posts: 143

Re: Find the ASCII code of a character in IML

That's a lot nicer, I shall have to look into upgrading.

SAS Super FREQ
Posts: 3,624

Re: Find the ASCII code of a character in IML

Here's one you can use without upgrading:

start chop(s);

   return( cshape(s,1,nleng(s),1) );

finish;

Frequent Contributor
Posts: 143

Re: Find the ASCII code of a character in IML

Thanks Rick, that's cool.   I never looked at cshape before.  The assumption would be that the functionality is similar to the regular shape function, but the size parameter makes it more powerful as you have shown.

Ask a Question
Discussion stats
  • 10 replies
  • 999 views
  • 2 likes
  • 3 in conversation