The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
The macro package includes several functions to manage the macro symbol table. These functions provide an interface between regular R code and the macro language.
The symbol table functions are as follows:
symput(): Adds a macro variable to the
macro symbol table.symget(): Gets a macro variable value
from the macro symbol table.symtable(): Extracts and views the
macro symbol table.symclear(): Clears the values from the
macro symbol table.In this article, we will look at the different ways the functions can be used, and how they can be used together.
Since the symbol table functions are regular R functions, they can be
used before or after the call to msource(). One common way
to use them is to set macro variable values for a standard macro
program, and then examine the symbol table after the standard macro
program completes.
For example, let’s say you have a template macro program to perform an analysis on some data. You want to specify the input dataset, the variables to perform the analysis on, and you want some control over which statistics are calculated.
Here is a sample program that meets the above criteria. It is included in the macro package as “Demo5.R”. Note the following about this template code:
%get_analysis() is defined in the
program, with three parameters.#% Demo5: Template Analysis Program %#
library(dplyr)
# Perform Analysis ------------------------------------
#% Macro for Dynamic Descriptive Stats
#%macro get_analysis(dat, var, stats)
anl_&var <- `&dat` |>
summarize(VAR = "&var",
#%if ("mean" %in% &stats)
MEAN = mean(`&var`, na.rm = TRUE),
#%end
#%if ("median" %in% &stats)
MEDIAN = median(`&var`, na.rm = TRUE),
#%end
#%if ("sd" %in% &stats)
SD = sd(`&var`, na.rm = TRUE),
#%end
#%if ("min" %in% &stats)
MIN = min(`&var`, na.rm = TRUE),
#%end
#%if ("max" %in% &stats)
MAX = max(`&var`, na.rm = TRUE),
#%end
END = NULL
)
#%mend
#% Loop through analysis variables
#%do idx = 1 %to %sysfunc(length(&vars))
#%let var <- %sysfunc(&vars[&idx])
#%get_analysis(&dat, &var, &stats)
#%end
#% Get datasets to bind
#%let dsets <- %sysfunc(paste0("anl_", &vars, collapse = ", "))
# Bind analysis datasets
final <- bind_rows(`&dsets`)
# Print results
print(final)As you can see, the above template program displays quite a bit of macro functionality.
Now let’s set some parameters and execute the template program. Note the following about the run below:
symput() functions are used to assign values to the
macro variables “&dat”, “&vars”, and “&stats”.msource() function is called with the “clear”
parameter set to FALSE. Setting the “clear” parameter to FALSE is needed
so that we do not wipe out the values assigned by
symput().symtable() function allows us to investigate the
macro symbol table at the end of the run.msource() function
is set to FALSE, it is a good practice to clear out the symbol table by
calling symclear(). That way, if we need to re-run the
program, we can start with a clean symbol table.library(macro)
# Get demo program
pth <- system.file("extdata/Demo5.R", package = "macro")
# Set macro variables
symput("dat", "mtcars")
symput("vars", c("mpg", "disp", "drat"))
symput("stats", c("mean", "median", "sd"))
# Macro Source demo program
msource(pth, clear = FALSE)
# ---------
# library(dplyr)
#
# # Perform Analysis ------------------------------------
#
#
# anl_mpg <- mtcars |>
# summarize(VAR = "mpg",
# MEAN = mean(mpg, na.rm = TRUE),
# MEDIAN = median(mpg, na.rm = TRUE),
# SD = sd(mpg, na.rm = TRUE),
# END = NULL
# )
# anl_disp <- mtcars |>
# summarize(VAR = "disp",
# MEAN = mean(disp, na.rm = TRUE),
# MEDIAN = median(disp, na.rm = TRUE),
# SD = sd(disp, na.rm = TRUE),
# END = NULL
# )
# anl_drat <- mtcars |>
# summarize(VAR = "drat",
# MEAN = mean(drat, na.rm = TRUE),
# MEDIAN = median(drat, na.rm = TRUE),
# SD = sd(drat, na.rm = TRUE),
# END = NULL
# )
#
# # Bind analysis datasets
# final <- bind_rows(anl_mpg, anl_disp, anl_drat)
#
# # Print results
# print(final)
# ---------
# VAR MEAN MEDIAN SD
# 1 mpg 20.090625 19.200 6.0269481
# 2 disp 230.721875 196.300 123.9386938
# 3 drat 3.596563 3.695 0.5346787
# View symbol table
symtable()
# # Macro Symbol Table: 6 macro variables
# Name Value
# 1 &dat mtcars
# 2 &dsets anl_mpg, anl_disp, anl_drat
# 3 &idx 3
# 4 &stats mean, median, sd
# 5 &var drat
# 6 &vars mpg, disp, drat
# # Macro Function List: 1 functions
# # Function '%get_analysis': 3 parameters
# - dat
# - var
# - stats
# Get a specific variable value
symget("dat")
# [1] "mtcars"
# Clear the symbol table
symclear()
# Clearing macro symbol table...
# 8 items cleared.Observe that the “final” dataset contains an analysis for all three requested variables. The macro parameters allow you change the input dataset, the analysis variables, and the statistics generated.
For illustration purposes, let’s run “Demo5.R” again with different parameters. This time we will use the “iris” dataset:
library(macro)
# Get demo program
pth <- system.file("extdata/Demo5.R", package = "macro")
# Set macro variables
symput("dat", "iris")
symput("vars", c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"))
symput("stats", c("mean", "median", "sd", "min", "max"))
# Macro Source demo program
msource(pth, clear = FALSE)
# ---------
# library(dplyr)
#
# # Perform Analysis ------------------------------------
#
#
# anl_Sepal.Length <- iris |>
# summarize(VAR = "Sepal.Length",
# MEAN = mean(Sepal.Length, na.rm = TRUE),
# MEDIAN = median(Sepal.Length, na.rm = TRUE),
# SD = sd(Sepal.Length, na.rm = TRUE),
# MIN = min(Sepal.Length, na.rm = TRUE),
# MAX = max(Sepal.Length, na.rm = TRUE),
# END = NULL
# )
# anl_Sepal.Width <- iris |>
# summarize(VAR = "Sepal.Width",
# MEAN = mean(Sepal.Width, na.rm = TRUE),
# MEDIAN = median(Sepal.Width, na.rm = TRUE),
# SD = sd(Sepal.Width, na.rm = TRUE),
# MIN = min(Sepal.Width, na.rm = TRUE),
# MAX = max(Sepal.Width, na.rm = TRUE),
# END = NULL
# )
# anl_Petal.Length <- iris |>
# summarize(VAR = "Petal.Length",
# MEAN = mean(Petal.Length, na.rm = TRUE),
# MEDIAN = median(Petal.Length, na.rm = TRUE),
# SD = sd(Petal.Length, na.rm = TRUE),
# MIN = min(Petal.Length, na.rm = TRUE),
# MAX = max(Petal.Length, na.rm = TRUE),
# END = NULL
# )
# anl_Petal.Width <- iris |>
# summarize(VAR = "Petal.Width",
# MEAN = mean(Petal.Width, na.rm = TRUE),
# MEDIAN = median(Petal.Width, na.rm = TRUE),
# SD = sd(Petal.Width, na.rm = TRUE),
# MIN = min(Petal.Width, na.rm = TRUE),
# MAX = max(Petal.Width, na.rm = TRUE),
# END = NULL
# )
#
# # Bind analysis datasets
# final <- bind_rows(anl_Sepal.Length, anl_Sepal.Width, anl_Petal.Length, anl_Petal.Width)
#
# # Print results
# print(final)
#
# ---------
# VAR MEAN MEDIAN SD MIN MAX
# 1 Sepal.Length 5.843333 5.80 0.8280661 4.3 7.9
# 2 Sepal.Width 3.057333 3.00 0.4358663 2.0 4.4
# 3 Petal.Length 3.758000 4.35 1.7652982 1.0 6.9
# 4 Petal.Width 1.199333 1.30 0.7622377 0.1 2.5
# View symbol table
symtable()
# # Macro Symbol Table: 6 macro variables
# Name Value
# 1 &dat iris
# 2 &dsets anl_Sepal.Length, anl_Sepal.Width, anl_Petal.Length, anl_Petal.Width
# 3 &idx 4
# 4 &stats mean, median, sd, min, max
# 5 &var Petal.Width
# 6 &vars Sepal.Length, Sepal.Width, Petal.Length, Petal.Width
# # Macro Function List: 1 functions
# # Function '%get_analysis': 3 parameters
# - dat
# - var
# - stats
# Clear symbol table
symclear()
# Clearing macro symbol table...
# 7 items cleared.By changing the macro parameters, we were able to perform a different analysis on a completely different set of data. A macro-enabled program such as this offers considerable flexibility over other methods. It would be troublesome to achieve such flexibility in a regular R program, especially one that makes heavy use of non-standard evaluation.
While the above scenario demonstrates the most common application of symbol table functions, there are some other scenarios where these functions may be helpful. Here are some of them:
symget() and
symtable() functions. You can use these to log incoming
macro parameter values, or log the state of the symbol table at the end
of the run.Next: Debugging
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.