R packaging, installation etc

November 30, 2020 — January 7, 2022

computers are awful
R
statistics
Figure 1

1 Installing R

The following seemed to be simplest for me on macos.

brew install --cask r

Note that brew install r without the cask part leads to some compilation issues for package dependencies

Sometimes I require a fancy ~/.R/Makevars setup to find the correct gfortran etc:

MAJVER=11
VER=11.1.0_1
CC=gcc-$(MAJVER)
CXX=g++-$(MAJVER)
CFLAGS=-mtune=native -g -O2 -Wall -pedantic -Wconversion
CXXFLAGS=-mtune=native -g -O2 -Wall -pedantic -Wconversion
FLIBS=-L/usr/local/Cellar/gcc/$(VER)/lib/gcc/$(MAJVER)

1.1 Apple Silicon

Homebrew on apple silicon is different. According to https://docs.brew.sh/Installation, /usr/local is for Intel binaries, /opt/homebrew for ARM. When using it to fulfil compilation dependencies some config is needed: Recommended config to go in ~/.R/Makevars:

CFLAGS   = -I/opt/homebrew/include
CPPFLAGS = -I/opt/homebrew/include
CXXFLAGS = -I/opt/homebrew/include

## R native
#FLIBS   = -L/opt/R/arm64/gfortran/lib
#F77     = /opt/R/arm64/gfortran/bin/gfortran
#FC      = /opt/R/arm64/gfortran/bin/gfortran

## homebrew alternative
FLIBS   = -L/opt/homebrew/opt/gfortran/lib
F77     = /opt/homebrew/bin/gfortran
FC      = /opt/homebrew/bin/gfortran

Various deps are useful

brew install v8

For ubuntu, it seems less troublesome to use the OS packages. First, add deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/ to the apt source list sudo vim /etc/apt/sources.d/r.list. Now, secure it, then install things.

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
sudo apt-get update
sudo apt-get install r-base r-base-dev

In either case, you can also install it via the package manager conda but this is not recommended because nothing at all seems to compile then.

2 Installing R packages

Classic style, you install a bunch of R packages in a central location and keep them up to date. Recommended: use some dependency management system such as renv, see below.

2.1 Smoother experience for macos

The repository https://macos.rbind.io (Github repo) provides some binary R packages for the Homebrew (cask) version of base R that are currently missing on CRAN, in a similar spirit as the “CRAN extras” repository for Windows: https://www.stats.ox.ac.uk/pub/RWin/. If you are using the Homebrew version of R on the latest version of macOS, you may set the repos option in R first via ~/.Rprofile:

options(repos = c(
  CRANextra = 'https://macos.rbind.io',
  CRAN = 'https://cran.rstudio.com'
))

Extra Binary R packages for the Homebrew R (Cask)

2.2 Choosing package location

Depending on when and how you install(ed) R your packages can end up in all manner of silly and inconsistent places.

The best plan is to specify somewhere consistent by setting R_LIBS_USER in your ~/.Renviron. For some setups the default value is R_LIBS_USER=~/R/%p-library/%v, although not for a fresh R install on my work machine, so I would recommend setting it to something to be safe. That default, ~/R/%p-library/%v, conservatively assumes you might share the same packages folder across multiple different platforms, which is unlikely for your own private computer, although not crazy if you are moving your use library to different architectures across upgrades. R_LIBS_USER=~/R/%v is might sufficient for normal people.

Note that it does not work if the folder does not exist:

> dir.exists(Sys.getenv('R_LIBS_USER'))
[1] FALSE

so in that case run this:

> dir.create(Sys.getenv('R_LIBS_USER'), recursive = TRUE)
> dir.exists(Sys.getenv('R_LIBS_USER'))
[1] TRUE

then restart R.

3 Dependency management

renv I think is the current preferred environment management system for a project which should have fixed dependencies. There is some older system called packrat which I gather we can all safely ignore as deprecated.

The general workflow when working with renv is:

  1. Call [renv::init()](https://rstudio.github.io/renv/reference/init.html) to initialize a new project-local environment with a private R library,
  2. Work in the project as normal, installing and removing new R packages as they are needed in the project,
  3. Call [renv::snapshot()](https://rstudio.github.io/renv/reference/snapshot.html) to save the state of the project library to the lockfile (called renv.lock),
  4. Continue working on your project, installing and updating R packages as needed.
  5. Call [renv::snapshot()](https://rstudio.github.io/renv/reference/snapshot.html) again to save the state of your project library if your attempts to update R packages were successful, or call [renv::restore()](https://rstudio.github.io/renv/reference/restore.html) to revert to the previous state as encoded in the lockfile if your attempts to update packages introduced some new problems.

capsule is a kind of ultralight renv-wrapper that allows you to test code against multiple specific packages and package versions.

A capsule is a stable project-specific R package library that you consciously choose to execute code within. Think of it as representing ‘production’, while your normal interactive R session represents ‘development’.

You develop interactively in a dynamic package environment. You run code for real in a well-defined static capsule. Periodically you’ll want to have your development environment reflected in the capsule as new stuff is integrated.

When sharing with others, a capsule is the fallback that ensures your code can always be run, no matter what issues appear in your collaborator’s development environment.

Pro tip: If you use a dependency system such as renv which creates an .Rprofile file to automatically execute the initialisation scripts then you will no longer be executing your system-wide .Rprofile. You may need to add a line to your project-local .Rprofile,

source(fs::path_home(".Rprofile"))

4 Writing packages

How do you do that? It’s not so hard, and as Hilary Parker points out, saves you time.

Those are the HOWTOs. Here are some useful tools.

Dirk Eddelbeutel explains using continuous integration for R via Rtravis.

4.1 easy project reload

Devtools for lazy people:

Make a folder called MyCode with a DESCRIPTION file. Make a subfolder called R. Put R code in .R files in there. Edit, load_all("MyCode"), use the functions.

4.2 Hadley Wickham pro-style

  1. Install his devtools.
  2. Use the Devtools/RStudio workflow.

Here’s an intro to the OO facilities of R — although I recommend going for a functional style as much as possible to avoid pain.

Hadley has written lots of useful helper tools for this process. Here are two:

pkgdown is an easy tool for documenting R packages:

pkgdown is designed to make it quick and easy to build a website for your package. You can see pkgdown in action at https://pkgdown.r-lib.org: this is the output of pkgdown applied to the latest version of pkgdown.

usethis

usethis is a workflow package: it automates repetitive tasks that arise during project setup and development, both for R packages and non-package projects.