# Frequently Asked Questions

Below are some frequently asked questions about the macro package. Click on the links below to navigate to the full question and answer content.

## Index

- Why did you create the macro package?
- What capabilities does the macro package provide?
- How does the macro package work?
- Can I create macro functions and do loops?
- Can I nest macro conditionals?
- How does %include work?
- What is the difference between symput() and %symput()?
- Why are the debug line numbers off?
- How can I use this package to generate code?
- Why should I use this package for code generation?

## Content

### Why did you create the macro package?

Q: R already has meta-programming capabilities. Why do you want to create a macro programming capability?

A: The macro package was motivated specifically for code generation. The goal is to generate a program where all variable values are resolved, and only the desired conditional code is included in the final program. This result requires a pre-processing and text replacement capability which is lacking in R. The macro package fills that need.

top

### What capabilities does the macro package provide?

Q: It seems the R macro package provides less features than SAS. What capabilities does it provide?

A: The macro package supports the following features:

- Macro Comments
- Macro Variables
- Macro Conditions
- Macro Include
- Macro Do Loops
- User-Defined Macro Functions
- Some Built-In Macro Functions

These features are the most essential features of the SAS macro language, and will allow you to do most of the things you can do in SAS. There are many built-in macro functions in SAS that have not been replicated in the macro package. The built-in macro functions included in the macro package are `%sysfunc()`, `%symexist()`, `%symput()`, and `%nrstr()`.

top

### How does the macro package work?

Q: I don’t quite get it. How am I supposed to use this package?

A: A macro-enabled R program is a standard R program, with macro commands added as code comments. These special comments act as pre-processor directives. The pre-processor directives are resolved by the pre-processor function `msource()`. What you will do is write your macro enabled program, and run it with the `msource()` function instead of the `source()` function. Normally, you will do this on the command line. By default, the `msource()` function will run the currently selected program in RStudio. Otherwise, pass the name of the program you want to run as the first parameter on `msource()`. The function will pre-process the program, resolve any macro statements, and then execute the resolved code.

top

### Can I create macro functions and do loops?

Q: I want to create a macro function. Does the macro package support it? What about do loops?

A: Yes. The package supports user-defined macro functions and do loops. The syntax is similar to SAS. Note that both of these features are text replacement operations. They are useful specifically when you want to replicate some chunk of code repeatedly. Be mindful of the difference between these macro capabilities and normal Base R functions and loops, and choose your approach appropriately.

top

### Can I nest macro conditionals?

Q: I have a complicated set of conditions that are nested several levels deep. Can I do that with the macro package?

A: Yes. The package supports nested conditionals. There is no limit on the number of nested levels.

top

### How does %include work?

Q: I see from the documentation there is a “%include” macro function. How does it work? Is it the same as SAS?

A: Yes. The “#%include” macro function replicates the basic functionality of SAS “%include”. Text from the included file will be extracted and inserted into the generated file. Any macro statements in the included code will be resolved normally.

top

### What is the difference between symput() and %symput()?

Q: There appears to be two functions, `symput()` and `%symput()`. Why? Don’t they do the same thing?

A: The `symput()` and `%symput()` functions are similar in that they take a value from regular R code and assign it to a macro variable. The difference is in the time they run. The `symput()` function runs at execution time, and the `%symput()` function runs in the macro pre-processor. This difference is quite significant, and that is why there are two different functions. The `symput()` function can be used in regular R code even before `msource()` is called. The `%symput()` function can only be used in a macro `#%let` statement, and will pick up values dynamically from the generated code.

top

### Why are the debug line numbers off?

Q: I’m trying to debug a macro. But the line numbers on the “In#” column don’t seem to match my program. What is going on?

A: The line numbers shown on the “In#” column represent every input line processed. These lines can come from different sources: the original program, any included code, any macro functions, and code inside do loops. That is why the line numbers do not necessarily match the original program one for one. When trying to find the line that is causing an error, take these additional sources into consideration.

top

### How can I use this package to generate code?

Q: In the documentation you mention that the macro package can be used as a code generator. How does that work?

A: To do code generation, simply supply an output path as the second parameter on `msource()`. When the second parameter is not supplied, the function will create a temporary output file. When the second parameter is supplied, the function will output the resolved code to the specified path. That file is the generated code.

top

### Why should I use this package for code generation?

Q: There are several ways to do code generation in R already. Why would I want to use the macro package?

A: The advantages of using the macro package for code generation are:

- It is easy to combine code from several files using the “#%include” command.
- Only the code inside TRUE macro conditions will be emitted to the output file. This feature makes the resolved code more compact and easier to read.
- Macro variables will be resolved to the actual variable value, instead of the variable name. For instance, a macro variable for a file path will resolve to the actual path, instead of just the variable name. This feature also makes the code easier to read and understand.
- You can write your macro program so that the emitted code runs independently, without any dependencies on external packages, systems, or functions. This feature makes the generated code self-contained, portable, and totally transparent.

top