Base SAS contains many functions for processing strings, and you can call these functions from within a SAS/IML program. However, sometimes a SAS/IML programmer needs to process a vector of strings. No problem! You can call most Base SAS functions with a vector of parameters.
I have previously written about how to convert a string into a character vector, but sometimes it is useful to do the reverse operation. Specifically, it is sometimes useful to create a single string from the elements in a SAS/IML character vector or matrix. The following SAS/IML module concatenates all of the elements in a SAS/IML matrix into a single string, stripping out blank characters at the beginning or end of each element. The module contains an optional argument that you can use to specify a delimiter between words:
proc iml; /* Given a character matrix, this module returns a string with the N elements separated by spaces or a user-specified delimiter. */ start MakeString(vv, delim=" "); v = rowvec(vv); if type(v)='N' then v = putn(v,"BEST6."); /* convert numbers to char */ N = ncol(v); s = ""; do i = 1 to N-1; s = s + strip(v[i]) + delim; end; return ( s + strip(v[N]) ); finish; /* Test the module. You might want to use ODS LISTING for printing because HTML does not display multiple blank characters */ varNames = "x1":"x5"; s1 = MakeString(varNames); x = {"I" "think" "that" "I" "shall" "never" "see"}; s2 = MakeString(x, "/"); colors = {"Red" "Blue" "Green"}; s3 = MakeString(colors, ", "); num = 1:5; s4 = MakeString(num, ","); print s1, s2, s3, s4; |
It is difficult to eliminate the DO loop in the module and truly vectorize this process. The problem is that the SAS/IML language uses fixed-length arrays, so every time you try to trim a vector or extract substrings, the resulting IML vector is re-padded with blanks!
However, if the strings all have the same prefix, as in the varNames example, then you can write some special code that uses the prefix information to eliminate the loop. The ROWCATC function concatenates the elements into a single string without any blanks. The TRANWRD function in Base SAS replaces each prefix "x" with " x", which adds a space between the variable names in this special case:
/* ROWCATC concatenates into a single string without blanks; Use TRANWRD to put blank before each "x" character */ s5 = strip(tranwrd(rowcatc(VarNames), "x", " x")); |
I've used this "vector to string" function several times, most recently when I was reading a parameter estimates table that was produced by a SAS procedure. I needed to print a single string that contained the name of the variables in the model, and this module made it easy.
2 Comments
Pingback: Create a SAS macro variable that contains a list of values
Pingback: A vector-to-string function for SAS IML - The DO Loop