RStudio:addins part 1. – code reproducibility testing
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Contents
Introduction
This is the first post in the RStudio:addins series. The aim of the series is to walk the readers through creating an R package that will contain functionality for integrating useful addins into the RStudio IDE. At the end of this first article, your RStudio will be 1 useful addin richer.
The addin we will create in this article will let us run a script open in RStudio in R vanilla mode via a keyboard shortcut and open a file with the script’s output in RStudio.
This is useful for testing whether your script is reproducible by users that do not have the same start-up options as you (e.g. preloaded environment, site file, etc.), making it a good tool to test your scripts before sharing them.
If you want to get straight to the code, you can find it at https://gitlab.com/jozefhajnala/jhaddins.git
Prerequisites and recommendations
To make the most use of the series, you will need the following:
- R, ideally version 3.4.3 or more recent, 64bit
- RStudio IDE, ideally version 1.1.383 or more recent
- Also recommended
- git, for version control
- TortoiseGit, convenient shell interface to git for those using Windows, with pretty icons and all
- Recommended R packages (install with
install.packages("packagename")
, or via RStudio’s Packages tab):
devtools
– makes your development life easiertestthat
– provides a framework for unit testing integrated into RStudioroxygen2
– makes code documentation easy
Step 1 – Creating a package
- Use
devtools::create
to create a package (note that we will update moreDESCRIPTION
fields later and you can also choose any path you like and it will be reflected in the name of the package)
devtools::create( path = "jhaddins" , description = list("License" = "GPL-3") )
In RStudio or elsewhere navigate to the
jhaddins
folder and open the projectjhaddins.Rproj
(or the name of your project if you chose a different path)Run the first check and install the package
devtools::check() # Ctrl+Shift+E or Check button on RStudio's build tab devtools::install() # Ctrl+Shift+B or Install button on RStudio's build tab
- Optionally, initialize git for version control
devtools::use_git()
Step 2 – Writing the first functions
We will now write some functions into a file called makeCmd.R that will let us run the desired functionality:
makeCmd
to create a command executable viasystem
orshell
, with defaults set up for executing an R file specified bypath
makeCmd <- function(path , command = "Rscript" , opts = "--vanilla" , outputFile = NULL , suffix = NULL , addRhome = TRUE) { if (Sys.info()["sysname"] == "Windows") { qType <- "cmd2" } else { qType <- "sh" } if (isTRUE(addRhome)) { command <- file.path(R.home("bin"), command) } cmd <- paste( shQuote(command, type = qType) , shQuote(opts, type = qType) , shQuote(path, type = qType) ) if (!is.null(outputFile)) { cmd <- paste(cmd, ">", shQuote(outputFile)) } if (!is.null(suffix)) { cmd <- paste(cmd, suffix) } cmd }
executeCmd
to execute a command
executeCmd <- function(cmd, intern = FALSE) { sysName <- Sys.info()["sysname"] stopifnot( is.character(cmd) , length(cmd) == 1 , sysName %in% c("Windows", "Linux") ) if (sysName == "Windows") { shell(cmd, intern = intern) } else { system(cmd, intern = intern) } }
replaceTilde
for Linux purposes
replaceTilde <- function(path) { if (substr(path, 1, 1) == "~") { path <- sub("~", Sys.getenv("HOME"), path, fixed = TRUE) } file.path(path) }
- And finally the function which will be used for the addin execution -
runCurrentRscript
to retrieve the path to the currently active file in RStudio, run it, write the output to a fileoutput.txt
and open the file with output.
runCurrentRscript <- function( path = replaceTilde(rstudioapi::getActiveDocumentContext()[["path"]]) , outputFile = "output.txt") { cmd <- makeCmd(path, outputFile = outputFile) executeCmd(cmd) if (!is.null(outputFile) && file.exists(outputFile)) { rstudioapi::navigateToFile(outputFile) } }
Step 3 - Setting up an addin
Now that we have all our functions ready, all we have to do is create a file addins.dcf under the \inst\rstudio
folder of our package. We specify the Name
of the addin, write a nice Description
of what it does and most importantly specify the Binding
to the function we want to call:
Name: runCurrentRscript Description: Executes the currently open R script file via Rscript with --vanilla option Binding: runCurrentRscript Interactive: false
Now we can rebuild and install our package and in RStudio’s menu navigate to Tools -> Addins -> Browse Addins...
, and there it is - our first addin. For the best experience, we can click the Keyboard Shortcuts...
button and assign a keyboard shortcut to our addin for easy use.
Now just open an R script, hit our shortcut and voilà, our script gets execute via RScript in vanilla mode.
Step 4 - Updating our DESCRIPTION
and NAMESPACE
As our last steps, we should
- Update our DESCRIPTION file with
rstudioapi
asImports
, as we will be needing it before using our package:
Package: jhaddins Title: JH's RStudio Addins Version: 0.0.0.9000 Authors@R: person("Jozef", "Hajnala", email = "[email protected]", role = c("aut", "cre")) Description: Useful addins to make RStudio even better. Depends: R (>= 3.0.1) Imports: rstudioapi (>= 0.7) License: GPL-3 Encoding: UTF-8 LazyData: true RoxygenNote: 6.0.1
- Update our NAMESPACE by importing the functions from other packages that we are using, namely:
importFrom(rstudioapi, navigateToFile) importFrom(rstudioapi, getActiveDocumentContext)
Now we can finally rebuild and install our package again and run a CHECK
to see that we have no errors, warnings and notes telling us something is wrong. Make sure to use the document = FALSE
for now.
devtools::install() # Ctrl+Shift+B or Install button on RStudio's build tab devtools::check(document = FALSE) # Ctrl+Shift+E or Check button on RStudio's build tab
What is next - Always paying our (technical) debts
In the next post of the series, we will pay our debt of
- missing documentation for our functions, that will help us to generate updates to our
NAMESPACE
automatically and help us get a nice documentation so that we can read about our functions using?
- and unit tests to help us sleep better knowing that our functions get tested!
Wrapping up
We can quickly create an RStudio addin by:
- Creating an R package
- Writing a function in that package
- Creating a
addins.dcf
in\inst\rstudio
folder of our package
TL;DR - Just give me the package
Use git clone from: https://gitlab.com/jozefhajnala/jhaddins.git
References
- RStudio IDE cheat sheet (4.4MB, pdf)
- RStudio IDE tricks you might have missed
- Understanding Addins - A fantastic webinar, where you can learn how to write and setup addins step-by-step
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.