In my recent post on how to understand character vectors in SAS/IML, I left out an important topic: How can you allocate a character vector of a specified length? In this article, "length" means the maximum number of characters in an element, not the number of elements in a vector.
In the SAS DATA step, you can use the LENGTH statement to specify the maximum number of characters that can be stored in a variable. Thus the length of a variable can be greater than the length of any string that it contains. However, the SAS/IML language does not support the LENGTH statement. This leads to an interesting problem: How can you create a vector in SAS/IML such that each element can contain up to k characters?
This problem comes up in statistical programming because sometimes you need to enforce a limit on the length of a character vector. For example, if you are creating strings that will be used to name SAS variables, the strings must not exceed 32 characters.
There are a couple of possible solutions. In SAS/IML 12.3, which was released with SAS 9.4, you can use the BLANKSTR function to create a blank string with a given number of characters. The following statements create a string that contains 10 space characters. You can then use the J function or the REPEAT function to create a character vector.
proc iml; /* generate blank strings of an arbitrary size */ maxChars = 10; /* maximum number of characters to store */ Blanks = BlankStr(maxChars); /* string of length 10 (SAS/IML 12.3) */ c = j(1, 5, Blanks); /* allocate 1x5 vector of blank strings */ |
If you do not have SAS/IML 12.3, use the SUBPAD function in Base SAS. The following statement duplicates the functionality of the BlankStr function.
Blanks = subpad(" ", 1, maxChars); /* return string of length 10 */ |
I'll leave it as an exercise to figure out why this call to the SUBPAD function creates a string with 10 blank characters!
Have you ever faced the problem of generating a string with a specified number of characters? What was your solution?
4 Comments
Rick, you showed me last year how useful CSHAPE was for chopping strings up, it's good for sticking them together too.
.
c = cshape(' ', 1, 5, 10);
Awesome tip. Here's a third way: c = rowcat(repeat(' ',5,10));
Or possibly: c = substr(' ', j(1, 5), 10);
Pingback: Overview of new features in SAS/IML 12.3 - The DO Loop