Believe it or not, I recently had to use SAS for a simulation study because it was the only system available that could maximize the exact partial likelihood of a Cox proportional hazards model for tied data (`ties=exact`

) in a reasonable amount of time for a data set of 2,000 observations. This was the first time I ran a simulation in SAS. I made use of the MACRO capabilities of SAS to write generic functions that could be used to repeat steps; I might blog about my overall experience some day. Today, I’ll just write about one source of frustration that I had.

In writing my simulation study, I made use of Macro Variables (`%let`

command) for the different scenarios I was investigating. After getting some unexpected results, I started debugging and then realized that whatever comes after the equal sign and before the semicolon of a `%let`

statement is what the macro variable stores. For example, if I specify `%let x = 2 + log(2) / λ ;`

, what gets stored in x is `2 + log(2) / λ`

. When I utilize `&x`

, `2 + log(2) / λ`

gets substituted in the code (I incorrectly assumed this expression was evaluated), which can lead to unexpected results if it were used in mathematical expressions. For instance, if in a data step I do `y = z / &x`

, then I might get something I wasn’t expecting: `z / 2 + log(2) / λ`

instead of `z / (2 + log(2) / λ)`

. I then thought I needed to use %EVAL or %SYSEVALF, but these functions only work with additions and not other mathematical functions (e.g., `log`

). I also considered using CALL SYMPUTN but it could only be used in a `DATA`

step. My solution for getting the right math is to always surround expressions with parentheses: `%let x = (log(2) / λ)`

. This way, it’s safe to use `&x`

as an entity.

To help with debugging and to see exactly how your code is running, I suggest the `symbolgen`

option be turned on when macros are used:

```
<pre class="example">options symbolgen ; /*show macro variable resolution*/
```

## Leave a Comment