Defining new metrics in Microstrategy with R integration
Microstrategy has a new R Integration Pack which allows you to use R scripts to calculate new Microstrategy metrics. Here are some tips on how to use it. I also have a sample R script that will call the qicharts
package.
Metric formula in MSTR
You invoke R from MSTR by defining a metric using the RScript
function. The barest minimum formula to invoke R is something like
RScript<_RScriptFile="Script.r">(Input, Input....)
where _RScriptFile
is the name of the R script you want to run, and Inputs are names of MSTR metrics to pass to the R script.
R Script inputs and outputs
Microstrategy invokes the R script and passes metrics by defining variables, A header in the R script tells the MSTR integration pack what variables to define in R before running the script:
#MICROSTRATEGY_BEGIN
#
#DESC This script takes 2 metrics from MSTR, makes a dataframe and adds them.
#DESC Revision A
#
#RVAR ParamName -parameter NumericParam1
#RVAR Metric1 -input -numeric -vector
#RVAR Metric2 -input -numeric -vector
#
#RVAR MetricSum -output -numeric -vector
#MICROSTRATEGY_END
This header says that two metrics can be passed to the script as inputs, and will be exposed as vectors in R, as variables named Metric1 and Metric2. These vectors can be turned into dataframes or used
directly. Vectors will be ordered as they appear in the report, or can be sorted explicitly with the SortyBy parameter: e.g., SortBy=(Month)
. If you specify -repeat
for the final input variable, the variable in R will be a matrix instead of a vector, with all subsequent inputs as matrix components.
The header also specifies what R variable is returned to MSTR as a metric. Your script can have multiple potential outputs, and the output can be selected via the _OutputVar
parameter to RScript within the angle brackets: RScript<..., _OutputVar="RVariableName">(...)
.
Parameters are also defined in the header, and passed within the angle brackets: RScript<_Params="ParamName=xxx">
. For example if you are using the qicharts package for control charts, you could pass the chart type (P, U, etc.) as a parameter, and expose the control limits (CL, UCL, LCL) as individual MSTR metrics by defining them as individual output vectors and selecting one with _OutputVar
.
Boilerplate for Package Dependencies, Error Handling and Testing
The R scripts provided by MSTR on the script “shelf” all have the same boilerplate for error handling, R package dependencies, and testing outside MSTR.
mstr.ErrMsg <- tryCatch({ #tryCatch for Exception Handling
if(exists("mstr.WorkingDir")) setwd(mstr.WorkingDir) #Working Directory if executed by MicroStrategy
#Check to see if package(s) are installed, install if not and then load
CheckInstallPackages <- function(pkgs) { #pkgs is a vector of strings with length >= 1
x <- lapply(pkgs, function(pkg){ #For each pkg in pkgs (attempt to load each package one at a time):
if(!do.call("require", list(pkg))) { # Load the package if available,
try(install.packages(pkg, lib=.Library,
repos="http://cran.rstudio.com")) # Silently attempt to install into the default library
tryCatch(do.call("library", list(pkg)), # Now attempt to load the package, catch error if it wasn't installed
error = function(err) { # Catch if we're unable to install into the default library
if(!interactive()) { # If non-interactive, install into this user's personal library
personalLibPath <- Sys.getenv("R_LIBS_USER") # Get the path to this user's personal library
if(is.na(match(personalLibPath, .libPaths()))) { # If the personal library is not in the list of libraries
dir.create(personalLibPath, recursive = TRUE) # Then create the personal library
.libPaths(personalLibPath) # And add the personal library to the list of libraries
}
install.packages(pkg, lib=personalLibPath, # Attempt to install the package into the personal library
repos="http://cran.rstudio.com") # if this fails, raise the error back to the report
do.call("library", list(pkg)) # Finally, attempt to load the package
}
}
)
}
})
}
#Get the data
if(exists("mstr.ExFlag")) { #If this is executed by MicroStrategy
# you can use inputs passed in from MSTR
} else { #If this is NOT via a MicroStrategy Report Execution
#NOT in MSTR, define test inputs
}
CheckInstallPackages(")
# YOUR CALCULATION HERE
#Finish
try(print("Success!")) #Print completion message when run from the console
mstr.ErrMsg <- "" #If we made it here, no errors were caught
}, error = function(err) { #Catch block to report an error
try(print(err)) # Print error message to console (using try to continue on any print error)
return(err$message) # Return error Message
})
Limitations in Enterprise mode
R visualizations are not useful in an enterprise setting. R integration with MSTR is only useful if you can think of the output of your R script as another metric in MSTR, equivalent to an additional column on a grid. This also means if you calculate multiple output vectors in the R script, as is common with control charts or forecasting, you will end up calling the R script multiple times from each MSTR metric.