The Nextjournal R Environment

This article builds reusable environments for R runtimes, based on the minimal Bash environment. The R version installed is .

Learn more about environments on Nextjournal.

You can quickly make use of the R environment by remixing the Nextjournal R template, or use these environments with any existing runtime by following these steps (see image below):

  • Activate the runtime settings in the sidebar.
  • Bring up the Environments dropdown.
  • Select the Import environment… item.
  • Search for this article, nextjournal/r-environment.
  • Select it to list all environments within.
  • Select the desired environment.

1. Showcase

These packages are included in Nextjournal's R 3.6 environment.

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

1.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.

R packages are installed using install.packages() or devtools::install_github() in an R cell. Please refer to the R section of Installing Software and Packages for more detailed information.

1.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.

1.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

1.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')
Loading viewer…

1.2.3. ggplot2

Plot with the ggplot2 package.

library(ggplot2)

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

1.3. Data Structures

2. Setup

The full setup starting from a minimal Ubuntu installation is below

2.1. Build a Minimal R Environment

Install R from the R 3.5/3.6 repository for Ubuntu. The build-essential package (which includes gcc) is a necessary prerequisite 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"), Ncpus=4)'

2.2. Build the Default R Environment

2.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, svglite, and shiny. 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",
                   "future", "shiny", "repr", "IRdisplay", "evaluate", "crayon", 
                   "pbdZMQ", "uuid", "digest", "R.matlab"), Ncpus=4)

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

2.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"]]