video

Do more with R: Write your own RStudio addins

This RStudio addins tutorial walks you step by step through creating an extension for the RStudio IDE

Writing RStudio addins is easy, is fun, and takes just a few minutes! Well, that’s what Hao Zhu from the Marcus Institute for Aging Research told the RStudio Conference recently. It hadn’t even occurred to me to try to write one, even though I use them pretty often. So I decided to try writing one to see if he was right.

My first question: What might I accomplish with an addin? According to RStudio’s Jonathan McPherson, an addin can help you write code, format code, integrate with external data, kick off scripts … basically, pretty much anything that regular R code can do.

Next question: How are they structured?

  • Addins are regular R code. More specifically, an addin is primarily an R function. But not just any function: It has to use the rstudioapi package somehow; that’s how the addin interacts with the RStudio IDE.
  • Addins need to be part of an R package. They can’t be a standalone function; they need a package structure around them.
  • And, addins need to include a .dcf file with information about each addin in a package—metadata in a specific format.

Here’s the surprisingly easy-to-write addin function that Zhu demoed at the RStudio Conference:

open_server_guide <- function() {
  rstudioapi::viewer("https://ifar-connect.hsl.harvard.edu/using_rstudio_server/")
}

I’ll walk you through how to build another addin: one to edit an RStudio R snippets file. That file is at ~/.R/snippets/r.snippets. You can open that file for editing with the usethis::edit_rstudio_snippets() function; by going several layers deep in the RStudio menu; or by running 

file.edit(paste0(path.expand('~'),'/.R/snippets/r.snippets'))

But let’s see how to make an addin to do the same thing.

First, you need an R package to put it in. 

You can set up a new package in RStudio with most of the directory structure you need by choosing File > New Project, choosing a new directory, and then choosing Package. Because snippets are arranged in alphabetical order by the name of their package and I want mine to be first, I named my package asnippet.

You can't just use 

file.edit(paste0(path.expand('~'),'/.R/snippets/r.snippets'))

in a function to open the snippets file. Remember: A snippet has to interact with the RStudio API, using the rstudioapi package inside a function. So instead you write a function that sends the file.edit() command to the RStudio console, using rstudioapi’s callFun() helper function:

edit_snippets <- function(){
rstudioapi::callFun("sendToConsole", "file.edit(paste0(path.expand('~'),'/.R/snippets/r.snippets'))")
}

This is a multistep way to do a simple thing, but one way that works to turn that function into an addin. rstudioapi's callFun() invokes an RStudio function. Which function? That's in the first argument: The function you want to call here is sendToConsole. And, as the name implies, that just means you’re sending code to the console. The second argument is what code you want to send to the console—in this case, the file.edit() code that open the snippets file.

The last piece for a working addin is a separate .dcf file: addins.dcf. That is a plaintext file, and it needs to live in a folder called rstudio under a folder called inst. Those folders aren’t created by default when you set up a package, so you need to create them manually. 

The addins.dcf file needs four lines of text for each addin: Name, Description, Binding, and whether it’s interactive. Name is what you want to call the addin. Description is probably fairly obvious. Binding is the name of your function for the addin. And interactive is either true or false: RStudio needs to know whether the addin is going to be waiting for user input. In this case, the answer is false.

Here's what's in the addins.dcf for this addin:

Name: Edit snippets
Description: Opens RStudio snippets file for editing
Binding: edit_snippets
Interactive: false

The addin name is Edit snippets, the description is Opens RStudio snippets file for editing, the binding—name of the function—is edit_snippets, and it’s not interactive. That’s it. Now I just need to build and load the package, which you can do from the RStudio build tab in the upper right pane.

If you've followed along and you look at your Addins dropdown, you should see Edit snippets under asnippet (or whatever you called your package).

RStudio addin dropdown IDG/Sharon Machlis

RStudio's addins dropdown

And if you click on the Edit snippets addin, your snippet file should pop open. 

Why do an addin instead of just running the function manually? One advantage of an addins is that you can assign a keyboard shortcut to it. Choose Tools > Modify Keyboard Shortcuts, search for your snippet, click next to the name, type in the keyboard shortcut you want, and press Apply. Now if you type that key combination, your snippet file should pop open for editing.

It looks like Zhu was right!

More resources: