In the SAS/IML language, the index creation operator (:) is used to construct a sequence of integer values. For example, the expression 1:7 creates a row vector with seven elements: 1, 2, ..., 7.
It is important to know the precedence of matrix operators. When I was in grade school, I learned the mnemonic "Please excuse my dear Aunt Sally" as a way to remember the precedence of arithmetic operators: parentheses, exponents, multiplication and division, and addition and subtraction.
When you use the index creation operator in SAS/IML, it has lower precedence that the arithmetic operators. Because the SAS/IML logical operators have the lowest precedence, a new mnemonic might be "Please eat my dear Aunt Sally's Italian lasagna." (Or, if Aunt Sally is a horrible cook, you can keep "excuse" in the phrase!)
Usually, low precedence is what you want. For example, to get the dates within a week in either direction, use the following:
proc iml; date = today(); twoweeks = date-7 : date+7; |
However, you need to be careful when you add a sequence of values to another quantity. For example, the following statements do NOT generate a vector with seven elements:
/** up to one week from date **/ week = date + 1:7; /** wrong! **/ |
The statement isn't correct because a+b*c:x+y*z is equivalent to (a+b*c):(x+y*z). However, this implies that the variable week is parsed as (date+1):7. The date 08AUG2011 has the SAS value 18,847, so the result is a row vector with values 18848, 18847,...8,7.
To offset a date, enclose the offset vector in parentheses:
/** up to one week from date **/ week = date + (1:7); /** correct **/ |
The only SAS/IML operators that have lower precedence than the index creation operator are the logical operators. For example, the following statement, which uses the AND operator (&), does not need additional parentheses:
if date + (1:7) > '01AUG2011'd & date + (1:7) < '01SEP2011'd then print "The dates are in August."; |