In this document we will describe the usage of the multiverse codeblock. The multiverse code block is an alternative to the R code blockwhich will parse any code run in it directly in the multiverse, andreduces the need for auxiliary functions such as (inside). In addition,the default analysis in the multiverse will be executed in theenvironment in which the multiverse has been declared, which wouldusually be the global environment. In that case the results of thedefault analysis can be inspected directly in an R code block, similarto what an user would do if they were running a single universeanalysis.
We demonstrate how the two methods are equivalent, and result in thesame multiverse.
In this example, we will use the data which compares differentmodalities for physical visualizations. See(frequentist-multiverse-analysis) for more details.
As with any multiverse analysis, we first need to define themultiverse object. This step is the same for both methods. We willdefine two separate objects for illustrating the two different ways ofadding code to the multiverse for analysis. In the multiverse analysisin this vignette, we will perform a log transformation on the durationvariable of the dataset using both theinside function aswell as themultiverse code block
The idea of the inside function is to allow us to write code to beexecuted within the multiverse and not directly in R, thus allowing usto make use of a flexible syntax for declaring the different possibleanalysis combinations within the multiverse. The inside function takestwo arguments:
{The expression passed into the multiverse is not executed directly,allowing us to parse and expand the expression provided by the user hasdeclared using ourbranch andparameters, intotheir corresponding analysis combinations.
Although the inside function is the only way to add code to themultiverse in an RScript, RMarkdown notebooks allow us the opportunityto use different language engines (not just limited to R). Thisflexibility also provides an opportunity to write multiverse codedirectly into a code block, instead of using auxillary functions.
The language associated with a code block is provided by the firstargument:```{r} Here the first argument isrhence the code in the associated block will be executed in R. To converta code block to execute in multiverse, change the first argument tomultiverse. Thus the code block would be:```{multiverse}
To execute a code block in multiverse, the user needs to provide twoadditional arguments:label andinside.
The label is a unique identifier for the code block, and each codeblock in the same document must have a different label. However, thelabel argument does not need to be explicitly specified (as is the casewith an R code block). Therefore,```{multiverse, label=default-m-1 ...},```{multiverse, default-m-1 ...} and```{multiverse default-m-1 ...} are all equivalent.
The inside argument takes in only multiverse objects, and is used toindicate the multiverse object which will the code inside the code blockwill be associated with. Thus declaring a multiverse code block wouldbe:```{multiverse, default-m-1, inside = M}
We provide the ability to declare multiverse code block as anAddIn in RStudio. Users can click onAddIns toolbarmenu in RStudio (see the image below). This would create a multiversecode block at the location of the cursor in the document.
Alternately, users can insert a multiverse We also allow users tocreate a keyboard shortcut to declare a multiverse code block inside aRMarkdown document. This can be done through the following steps:
If you are experiencing issues creating a keyboard shortcut for codeblocks, or if you are experiencing a situation where the shortcut needsto be re-created everytime you open a new RStudio session, please referto theDebugging Keyboard Shortcuts section at the end ofthis document.
The declaration of the chunk below is (this gets hidden when we knitthe document):```{multiverse default-m-1, inside = M_block}
```{multiverse default-m-1, inside = M_block}data_transform <- branch(data_transform, "log-transformed" ~ log, "untransformed" ~ identity )duration <- do.call(data_transform, list(userlogs$duration))```The result of this code block will be identical to the result usinginside(). We first compare whether the multiverse table isgenerated properly for both the multiverse objects.
## # A tibble: 2 × 6## .universe data_transform .parameter_assignment .code .results .errors## <int> <chr> <list> <list> <list> <list> ## 1 1 log-transformed <named list [1]> <named list> <env> <lgl> ## 2 2 untransformed <named list [1]> <named list> <env> <lgl>## # A tibble: 2 × 6## .universe data_transform .parameter_assignment .code .results .errors## <int> <chr> <list> <list> <list> <list> ## 1 1 log-transformed <named list [1]> <named list> <env> <lgl> ## 2 2 untransformed <named list [1]> <named list> <env> <lgl>As you can see above, both the methods yield the same multiversetable. Next, we inspect the.code column of the multiverseobject. This column contains the code used to generate each analysiscombination in the multiverse. The only differences here arise from howthe expressions are stored. The multiverse code block creates a namedlist, whereas the inside function creates a unnamed list for each row ofthis column.
Below is the output from the first multiverse object(M_inside), which uses the inside function:
## [[1]]## [[1]]$`1`## {## data_transform <- log## duration <- do.call(data_transform, list(userlogs$duration))## }## ## ## [[2]]## [[2]]$`1`## {## data_transform <- identity## duration <- do.call(data_transform, list(userlogs$duration))## }This is the output from the second multiverse object(M_block), which uses the multiverse code block:
## [[1]]## [[1]]$`default-m-1`## {## data_transform <- log## duration <- do.call(data_transform, list(userlogs$duration))## }## ## ## [[2]]## [[2]]$`default-m-1`## {## data_transform <- identity## duration <- do.call(data_transform, list(userlogs$duration))## }During interactive use with RStudio,multiverse code blockswill work very similarly to a R code block. It will only execute thedefault analysis (i.e. the analysis path obtained by combining the firstoption of each parameter) in the global environment. Any output that isgenerated will have the formatting that output of R code blocks do.
When a document is knit, currently all analysis paths are executedbut the document only shows the analysis path corresponding to thedefault analysis. We are currently developing interactive features whichwill allow the author to implement interactivity into the rendered HTMLdocument; this will also allow readers to interact with the analysis andinvestigate the robustness of the implemented analysis themselves.
Currently we do not support knitting of RMarkdown documents withmultiverse code blocks to PDF documents.
One issue that I have encountered in the past, is that I had tocreate the keyboard shortcut everytime I opened a new RStudio session.As discussed here, RStudio keybindings are saves as JSON files in thedirectory~/.R/rstudio/keybindings/, but this directory wasmissing for me.
Check if the directory exists for you: 1. Open Terminal 2. Enter:cd ~/.config/rstudio/keybindings
If it returns an error such ascd: no such file or directory, this means that you do nothave the directory. The fix is to create this directory which can bedone through the following steps:
mkdir ~/.config/rstudio/keybindings/If it returns “Permission denied” you might have to run the commandas the superuser in the Terminal:sudo mkdir ~/.config/rstudio/keybindings/ This will requestyou to enter your login password.