The Nextjournal R Environment

This article builds reusable environments for R runtimes, based on a minimal Bash environment. The R version installed is . The packages and package versions installed in this default environment are listed in the table below:

library(dplyr)
installed.packages() %>%
        as_tibble() %>%
        select(Package, Version)
0 items

To make use of an environment from this article, follow these steps:

  • Create a new article, and insert an R cell.
  • Activate the runtime settings in the sidebar (see image below).
  • Bring up the Environments dropdown.
  • Select the Import environment… item.
  • Search for this article, nextjournal/r-environment, by entering 'r-env' into the search field.
  • Select it to list all environments within.
  • Select the desired environment.

1. Setup

The full setup starting from a minimal Ubuntu installation is below

1.1. Build a Minimal R Environment

Install R from the R 3.5 repository for Ubuntu. build-essential is a necessary pre-requisite for installation of some R packages.

echo 'deb https://cloud.r-project.org/bin/linux/ubuntu bionic-cran35/' > \
  /etc/apt/sources.list.d/r35.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9

apt-get -qq update
DEBIAN_FRONTEND=noninteractive \
  apt-get install --no-install-recommends \
  build-essential \
  r-base
apt-get clean
rm -r /var/lib/apt/lists/* # Clear package list so it isn't stale

Setup package install options.

echo 'local({
  r <- getOption("repos")
  r["CRAN"] <- "https://cloud.r-project.org"
  options(repos = r, download.file.method = "libcurl")
})' > /etc/R/Rprofile.site

Install two necessary packages for R to work on Nextjournal.

R -e 'install.packages(c("base64enc", "jsonlite"))'

1.2. Build the Default R Environment

1.2.1. Install

Install the rest of the build tools, some required libraries, and other libraries that R needs for development.

apt-get -qq update
apt-get install --no-install-recommends \
  gfortran cmake automake libtool libltdl-dev pkg-config \
  libssh2-1 libcurl4-openssl-dev libssl-dev libxml2-dev libcairo2-dev \
  r-base-core r-base-dev
apt-get clean
rm -r /var/lib/apt/lists/* # Clear package list so it isn't stale

To support Jupyter we need a Python installation. We'll copy the minimal install code from the Nextjournal Python Environment, and install the Jupyter package.


conda install jupyter

This default image has support for tidyverse, plotly, and svglite. The package also makes some basic utilities available, as well as devtools to help facilitate the use of certain packages. Remaining packages are installed to support the Jupyter IRkernel.

install.packages(c("feather", "devtools", "tidyverse", "plotly", "svglite",
                   "repr", "IRdisplay", "evaluate", "crayon", "pbdZMQ",
                   "uuid", "digest", "R.matlab"))

Plotly will complain without the dev version of ggplot2. We also want the dev version of the IRkernel.

devtools::install_github(c("hadley/ggplot2", "IRkernel/IRkernel"))

Setup default fonts for built-in plots, and when ggplot2 and/or svglite are loaded. This .Rprofile will be mounted to root's home directory, and saved with the environment.

local({
  if (file.exists("/usr/share/fonts/truetype/Fira_Sans") || 
      file.exists("/usr/share/fonts/truetype/dejavu")) {
    fonts <- "Fira Sans,PT Sans,Open Sans,DejaVu Sans,sans-serif"
  } else {
    fonts <- "sans"
  }
  options(nextjournal.svg.device.default.fonts = fonts)
})

setHook(packageEvent("ggplot2", "onLoad"), 
  function(pkgname,pkgpath) {
    if (file.exists("/usr/share/fonts/truetype/Fira_Sans") || 
        file.exists("/usr/share/fonts/truetype/dejavu")) {
      fonts <- "Fira Sans,PT Sans,Open Sans,DejaVu Sans,sans-serif"
    } else {
      fonts <- "sans"
    }
    options(nextjournal.ggplot.device.default.fonts = fonts)

    ggplot2::theme_update(text = ggplot2::element_text(family = fonts))
  })

setHook(packageEvent("svglite", "onLoad"), 
  function(pkgname,pkgpath) {
    # Function to build a font alias with all four standard faces, 
    # needed because font filenames are not standardized.
    faces <- function(fam,base,r,i,b,bi) {
      list(plain = list(alias = fam, file = paste0(base,r)),
          italic = list(alias = fam, file = paste0(base,i)),
            bold = list(alias = fam, file = paste0(base,b)),
      bolditalic = list(alias = fam, file = paste0(base,bi)))
    }
    if (file.exists("/usr/share/fonts/truetype/Fira_Sans") && 
        file.exists("/usr/share/fonts/truetype/PT_Serif")) {
      fonts <- list(
        sans = faces("Fira Sans,PT Sans,Open Sans,DejaVu Sans,sans-serif",
                     "/usr/share/fonts/truetype/Fira_Sans/FiraSans-",
                     "Regular.ttf","Italic.ttf",
                     "Bold.ttf","BoldItalic.ttf"),
       serif = faces("PT Serif,Noto Serif,DejaVu Serif,serif",
                     "/usr/share/fonts/truetype/PT_Serif/PT_Serif-Web-",
                     "Regular.ttf","Italic.ttf",
                     "Bold.ttf","BoldItalic.ttf"))
    } else { # Fallback for older environments which only had DejaVu fonts
      fonts <- list(
        sans = faces("DejaVu Sans,Fira Sans,PT Sans,Open Sans,sans-serif",
                     "/usr/share/fonts/truetype/dejavu/DejaVuSans",
                     ".ttf","-Oblique.ttf",
                     "-Bold.ttf","-BoldOblique.ttf"),
       serif = faces("DejaVu Serif,PT Serif,Noto Serif,serif",
                    "/usr/share/fonts/truetype/dejavu/DejaVuSerif",
                    ".ttf","-Italic.ttf",
                     "-Bold.ttf","-BoldItalic.ttf"))
    }
    options(nextjournal.svglite.device.default.fonts = fonts)
  })
.Rprofile
R

1.2.2. Test

strsplit(R.version.string," ")[[1]][[3]]
IRkernel::installspec(user = FALSE)
jupyter kernelspec list
jupyter --version
jupyter --paths
cat /usr/local/share/jupyter/kernels/ir/kernel.json
cp /usr/local/share/jupyter/kernels/ir/logo-64x64.png /results/logo.png
packageDescription("Rcpp")[["Version"]]
packageDescription("tidyverse")[["Version"]]
packageDescription("plotly")[["Version"]]
packageDescription("ggplot2")[["Version"]]
packageDescription("jsonlite")[["Version"]]
packageDescription("svglite")[["Version"]]
packageDescription("feather")[["Version"]]

2. Showcase

The following packages are included in Nextjournal's R 3.5 environment.

2.1. System Packages and Basics

A number of support libraries are installed, as well as gcc v7 for installing Rcpp and other packages that require compilation.

The Rcpp package version allows for tight integration between R and C++ codes and libraries. The Tidyverse is also installed—this is a set of several data science packages which all follow certain design, grammar, and structural characteristics.

2.2. Plotting

Three plotting methods are available in the default environment. The built-in R plotting system works automatically to create static plots, Plotly v provides full access to the functionality of Plotly on R to generate figures with basic interactivity, and ggplot2 v syntax can be used either statically or with Plotly's ggplotly() function, which will add some interactivity.

2.2.1. R

x <- seq(-10, 10, length= 60); y <- x
f <- function(x, y) { r <- sqrt(x^2+y^2); sin(r)/r }
z <- outer(x, y, f)
persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "#009caa"); NULL

2.2.2. Plotly

This syntax allows full access to the functionality of Plotly on R.

library(plotly)

d <- diamonds[sample(nrow(diamonds), 1000), ]
plot_ly(d, x = ~carat, y = ~price,
  # Hover text:
  text = ~paste("Price: ", price, '$<br>Cut:', cut),
  color = ~carat, size = ~carat, type='scatter', mode='markers')

2.2.3. ggplot2

Plot with the ggplot2 package.

library(ggplot2)

qplot(speed, dist, data=cars) + geom_smooth()