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
Contents
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 = "jozef.hajnala@gmail.com", 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
- Get the status of the package after this article
- or use
git clone
fromhttps://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