Two of my favorite string-manipulation functions in the SAS DATA step are the COUNTW function and the SCAN function. The COUNTW function counts the number of words in a long string of text. Here "word" means a substring that is delimited by special characters, such as a space character, a period, or a comma. The SCAN function enables you to parse a long string and extract words. You can specify the delimiters yourself or use the default delimiters. Ron Cody discusses these and other string manipulation functions in his excellent 2005 tutorial, "An Introduction to SAS Character Functions."
Using the COUNTW and SCAN functions in the DATA step
For example, the following DATA step reads in a long line of text. The COUNTW function counts how many words are in the string. A loop then iterates over the number of words and the SCAN function extracts each word into a variable:
data parse; length word $20; /* number of characters in the longest word */ input str $ 1-80; delims = ' ,.!'; /* delimiters: space, comma, period, ... */ numWords = countw(str, delims); /* for each line of text, how many words? */ do i = 1 to numWords; /* split text into words */ word = scan(str, i, delims); output; end; drop str delims i; datalines; Introduction,to SAS/IML programming! Do you have... a question? ; proc print data=parse; run;
Notice that the delimiters do not include the '/' or '?' characters. Therefore these characters are considered to be part of words. For example, the strings "SAS/IML" and "question?" include those non-letter characters. Notice also that consecutive delimiters are automatically excluded, such as extra spaces or the ellipses marks.
Creating a vector of words in SAS/IML
One of the advantages of the SAS/IML matrix language is that you can call the hundreds of functions in Base SAS. When you pass in a vector of arguments to a Base SAS function, the function returns a vector that is the same size and shape as the parameter. In this way, you can vectorize the calling of Base SAS functions. In particular, you can pass in a vector of indices to the SCAN function and get back a vector of words. You do not need to write a loop to extract multiple words, as the following example demonstrates:
proc iml; s = "Introduction,to SAS/IML... programming!"; delims = ' ,.!'; n = countw(s, delims); words = scan(s, 1:n, delims); /* pass parameter vector: create vector of words */ print words;
In summary, Base SAS provides many useful functions such as the string manipulation functions. This article shows that when you call these functions from SAS/IML and pass in a parameter vector, you get back a vector of results.