How to test against almost any R version with VSCode and Docker

Last week I hit a spot of bother trying to test against R-devel using Rhub. The issue is now fixed but it was blocking all builds against R-devel for a few days.

While that was being resolved I decided to try using VSCode’s docker integration to test against the Rocker R-devel container locally. This turned out to be quite easy! So here’s how you can test locally against any R version that has a tagged Rocker Docker container version!


To pull this off you’ll need:

Step 1: ‘Reopen in container’

Click the little stylised >< icon in the bottom left corner. It’s bright purple in my screenshots. It will open the remote development menu. Choose Remote Containers: Reopen in container:

Step 2: ‘Add Development Container Configuration Files’

From the next menu you will be offered some default containers for Linux distributions. If you choose Show all definitions…, You will be offered R (community) - choose it!

Step 3: Wait for container to download

This starts the process of reopening your project in the container. You will have to wait for the container to download. This took a few minutes for me.

Step 4: Set the container tag version

Your project should have opened in the rocker/r-ver:latest container. If you open an R terminal you should be able to confirm that R is the latest release version. This is pretty sweet, but what we want is to be running against rocker/r-ver:devel.

To configure this we have to alter some files VSCode has placed in your project directory. You will have a new folder called .devcontainer under the project root:

├── .Rbuildignore
├── .devcontainer
│   ├── Dockerfile
│   ├── devcontainer.json
│   └── library-scripts
│       └──

We need to make a small change to Dockerfile and devcontainer.json.

In Dockerfile, change the line right at the start that has:

ARG VARIANT="latest"



The hardcoding of “latest” stops us being able to set it in the devcontainer.json.

Now in devcontainer.json, change this bit of JSON that has:

	"name": "R (Community)",
	"build": {
		"dockerfile": "Dockerfile",
		// Update VARIANT to pick a specific R version: latest, ... ,4.0.1 , 4.0.0
		"args": { "VARIANT": "latest" }


	"name": "R (Community)",
	"build": {
		"dockerfile": "Dockerfile",
		// Update VARIANT to pick a specific R version: latest, ... ,4.0.1 , 4.0.0
		"args": { "VARIANT": "devel" }

Make sure both of those are saved.

Step 5: Rebuild container

Using the stylised >< icon in the bottom left corner access the remote development menu and choose: Remote Containers: Rebuild container

The container will now rebuild via much the same process as step 3.

Step 6: Confirm you’re in R-Devel

Now when the project opens you can open an R terminal and run version to confirm you’re running against devel:


And that’s it. Now you can run devtools::test() and check() againt R-devel.

We could also go back to previous releases with this method by setting other tags in the devcontainer.json see available tags on the r-ver container here - they go back to around 3.2!

Using the remote development menu (><) we can flip back to our local R environment by choosing Remote Containers: Reopen Locally.

After the container versions have been downloaded the first time, flipping back and forth between local and container environments via >< takes just a couple of seconds!


#rstats tip: Use R-universe to harden yourself against CRAN irrationality. Here’s me installing {targets}, which is currently archived for nonsensical reasons.

Hey friends I’ve been off Twitter now for 34 days. I feel great. More focussed, greater attention span, happier.

These are syndicated posts coming from my account.

I am tracking some #rstats Twitter stuff via RSS. But I’m not checking DMs. I’m open to chat via email or Slack spaces we share.

Withholding my CRAN submission #rstats

I spent the last few nights polishing up a new submission for CRAN. I had planned to submit today. However I learned someone I greatly respect, whom I know to be almost certainly the most responsive and generous package maintainer in the #rstats community, has become the latest victim of CRAN irrationality and toxicity. I am sure he didn’t deserve to have his weekend ruined because one old curmudgeon can elect to punish people without any accountabilty.

And what about the bystanders who are going to attend work tomorrow and find their builds are no longer reproducible, because a keystone package was archived? Do they deserve that punishment too?

I am withholding my submission for now. I am not sure what to do. I don’t want to enable this behaviour, but I also want to make a tool I am enjoying as accessible as possible. A lot of thoughts are swirling about this. There’s more to write with a cooler head.

Recently I mapped out our #rstats centric public service data science stack for runapp. Here’s some words on the collaboration blob:…


Talking about this to my R-nerd friends in the R Users Network: Australian Public Policy (Runapp) this week.

A bunch of software logos with a large lens flare exploding from R

#rstats work project dependency usage over the last 2 and a bit years

Unsung dev heroes miss out like: styler, mapview, lintr, languageserver, mapedit et. al.

A bar plot of R package use frequency by year

This moment had me reflecting on the etymology of the word “parking’.

This $3k rig is standing in for a second car for us. Day care and shopping runs are no sweat. And the kids love it!

#Brisbane PSA: the best day to hit your local supermarket is the day after lockdown, once all the preppers have stopped thronging in the aisles.

  • yours truly, common sense

Approximating #rstats RStudio’s F2 shortcut in VSCode

I made an approximate equivilant to RStudio’s default F2 shortcut for VSCode. In RStudio this key opens a function definiton in a new editor tab.

The JSON from my settings.json:

    "key": "b",
    "name": "browse function source in new window",
    "type": "command",
    "command": "r.runCommandWithSelectionOrWord",
    "args": "rstudioapi::documentNew(paste0(as.character(styler::style_text(deparse($$))), collapse = '\\n'))"

I use a shorcut sequence , c b with the VSCode whichkey extension so your setup will probably look a bit different for "key".

A major drawback of this approach is that since it’s not a saved file, the language mode is not automatically detected, so I have to set the language mode to R to see syntax highlighting etc.

You could also make it show up slightly faster by avoiding styling the code, but I find this is a vast improvement over the default styling.

Magpies have started sneaking in the back door to steal the kids scraps from under the table and TBH I’m not even mad.

Let’s stop doubly-screwing data science learners

I frequently see tweets that highlight the fact that people learning coding are not taught in depth about fundamental tools or processes like using a linter, or debugging. For example, this blog post from Greg Wilson.

It’s possible that in Data Science land we are doubly-screwing over learners by not only not teaching them fundamental coding knowledge, but also not teaching analogous things in our own domain.

I know of one particularly progressive course in Business Analytics at Monash University that teaches RMardkown for writing analytical documents, and even touches on Shiny for interactive apps. Students are rightfully being taught how to put together a polished looking piece of data driven communication as core coursework.

To me this a really insightful move, because out here in the trenches I have seen and felt the pain first hand of people who think they are on to a winning idea, but can’t make it connect, due to inability to communicate it in a convincing way. My sense is that Monash’s approach is the exception rather than the rule, and that is doing students a disservice.

The big one, the one that I think DS educators are totally sleeping on, is building project pipelines. By that I mean the craft of building out scalable software machines that ingest data from various sources and transmute it into various outputs, probably involving aforementioned presentation layer technology for the final leg.

Tools in this space are becoming mature and ubiquitous. It seems that every big data driven tech company has had to build one, and a few have open sourced them. Examples: Airbnb and Airflow, Spotify and Luigi, Netflix and Metaflow. In the R world we have been very fortunate to have the rOpensci peer-reviewed option in {drake}, and soon we’ll have another peer-reviewed option in {targets}.

I have written at some length about {drake}, and how its benefits can be felt all the way down to small projects. Recently a colleague of mine who is studying told his lecturer and tutors about our {drake} workflow, and was invited to teach his class about it. At least some of his peers, data science students, are now using it for their assignments and raving about it.

This confirms to me that pipeline tools, and the principles that underpin them are ready to be incorporated into the canon of core Data Science knowledge. I really hope I hear of more institutions following Monash’s lead, and teaching students modern tools, arising from the data science domain, that can set them up for success in industry.


I’ve been writing a fair bit of Typescript and #rstats in VSCode over the last month and I’m struck by how much confidence the TS type linting gives me to slash at the code base. Editor highlights all the things I’ve broken quite well. Most of the bugs have been in the R code…

Keyboards vs. developer skill and the virtuos loop of productive developers

A bit of nonsense in the Twitterverse this week about developer seniority and usage of the mouse.

I see this as recurrence of the long running thread that rears up now and again about how ‘real’ developers use keyboard-driven editors like Emacs or Vim.

Some thoughts:

There could be a loose correlation between seniority and keyboard driven editors due to:

  • Age. These are old tools, and the people who started out when they were cutting edge are now old, and yes senior developers.
  • Injuries. Ergonomically, a mouse and standard size keyboard just don’t work long term for a segment of the population. Ergonomic keyboards, and keyboard mappings in keyboard-driven editors are a common solution to this. But you have to be at a mouse and keyboard for a fair amount of time for this to become a pain issue - skill accumulated over that time again probably leads to a loose correlation with developer seniority.

So I think some people might be observing a signal that is real (if weak), but surprise surprise getting themselves snagged in the correlation-causation-conundrum.

I have my own theories about better markers for productive programmers. I think after you gain enough programming skill you reach an inflection point where that skill can be brought to bear not just on the problems you have, but on your processes for solving them. You can write code to make yourself more efficient at writing code. You craft your own tools to fit your own niche problems.

There are examples of people who are known to be highly productive doing this everywhere. In the R world think about how {knitr}, {devtools}, {usethis}, {reprex} and their like came to be. They’re programming/CLI tools intended to supplement the capabilities of a GUI in a composite interface to the niche problems of building documents, packages, projects, and examples.

An interesting thing often happens where these things start out as command line things, and become so important to a workflow that they graduate to a keybinding or a GUI button. And so here I think we encounter another loose correlation between preference for keyboard-driven and seniority:

If you’re in the business of crafting the interface to your workflow, keybindings or buttons allow you to reduce the friction of that interface and make it ‘feel’ nicer to use. I guess it’s like the digital equivalent of a wall-mounted pegboard for tools. Having all these for-purpose tools right at your fingertips, you can reach for without thinking, helps you focus on what’s on the bench.

You could array your tools with buttons or menus to be moused-on, but keybindings give you a bit more ‘space’ to work with before things get unweildly - you run out of pixels fast! So there’s a practicality aspect that could be a driver for keybindings and editors that make keybindings easy to execute.

But it’s not creation of buttons or keybindings that is important. What exactly is a ‘low friction’ inteface will vary by person, and is relative to the friction of the task being interfaced with. In fact if you have powerful commands, a sharp memory, and are a fast typist, maybe a CLI already feels friction free.

The important thing - the productity multiplier - is using your skills to shape your tools and the environment that you work in, which in-turn makes your skills more effective. It’s an extremely virtuos loop, and I think possibly what people are really aspiring to, rather than say mastery of the keyboard or a keyboard-driven editor like Vim or Emacs.

Commands, buttons, bindings, foot pedals, voice commands, gesture controls… these are all just implementation options for interfaces created by that virtuos loop.

Howdy eveyrone it’s me Acrobat Reader. I’m a Reader for Pee Dee Effs. Definitely gonna write-lock those suckers tho (haha), so don’t forget to close me down or I’m gonna have to derail the shit out of your rendring pipelines. Seriously, I will DESTROY them. Have a great day!

Can one get a Phd in the fiddly little offset maths involved in inserting text into documents programatically?

Feeling like a bit of an outlier while wistfully throwing name in hat for Github codespaces. Also a Vim checkbox but no Emacs!

I have a feeling this is going to shake things up quite a bit when it drops.

Just ripped through @alexsmann and Co’s ‘The Eleventh’ in a few days:…

Great Australian historical storytelling!

We bought a pair of high end noise cancelling headphones, and now my partner is 5m away from me working on her board report while I am doing guitar drills. This is the greatest thing ever!

This Outlook spam caught my eye today. 27 days in the last month where work hasn’t leaked into home time. I’m actually quite proud of this summary statistic!

I do resent the label though. The days are contained but they aren’t that ‘quiet’!

Debugger in the works for #rstats and VSCode looks like a handy tool:…

Hey #rstats I recommend giving ‘The Social Dilemma’ on Netflix a watch.

Right now I’m reflecting on how much we are using Twitter to connect on R topics versus how much Twitter is using that pretext as an excuse to jack us in to the money printing machine. 🤔

Me: => x.thing.thingo) JS: Yeaaahhh boi Inline lambda. Nice one! Me: => {x.thing.thingo}) JS: NOPE. I WILL NEVER. HOW COULD YOU POSSIBLY?! GET OUT.