Skip to contents

Development workflow

These notes describe my personal workflow when working on this package, and is subject to change.

Download

A local version of the package can be obtained by downloading the zipped repository from our GitHub organisation page, by selecting Code > Download ZIP. This downloads the entire repository, including files related to development that won’t be included in the package available to end users. Or, if you use git, clone the repository in the usual way,

git clone git@github.com:surveygraph/surveygraphr.git

When it is made available on CRAN, we’ll be able to download and install in a single step by running

install.packages("surveygraph")

This is important for discoverability, as we want to assume that users won’t be comfortable building from source, or even installing from GitHub, as can be done using the devtools package. We elaborate on this below.

Build and install from source

Note that neither of the download options (downloading a zip and git cloning) in the previous section actually installs the package. To build using the downloaded source (after unzipping if necessary), open a terminal and run

R CMD BUILD .

This compiles the *.cc source files to produce *.o object files, then bundles them to create a *.so shared object file. (The build command does a few other things too…). [Say something here about ddl files, the NAMESPACE doc, R files etc etc.] To install the [?] files, we run

R CMD INSTALL .

and the package is ready to use in an interpreter. Alternatively, the package can be installed from GitHub by running the following commands in an R interpreter.

library("devtools")
devtools::install_github("surveygraph/surveygraphr")

Note that it remains to solve the awkward problem of overloading the term “surveygraph”, which is the ideal final name of both the R and Python packages, but which necessitate different repository names in our organisation.

Testing

The standard check for R projects is R CMD check which i

R CMD check .           # run especially before CRAN submissions
R CMD SHLIB src/*.cc    # for building shared object files

Following the convention of the tidyverse, we carry out unit tests using the testthat package.

Debugging

One can debug on the level of shared objects directly using dyn.load, as well as running .Call directly

Documentation workflow

Object documentation

To build object documentation, we run devtools::document(), which in turn calls roxygenise() from the roxygen2 package. This function looks for roxygen2 comments in markdown above R functions in the R/ directory. We comment in markdown all exported functions in the R/ directory. These comments are then translated to produce .Rd files in the man/ directory. Further, roxygen2 will also build the NAMESPACE file based on the @export function tags.

The script buildman.R contains the commands

library("devtools")

devtools::document()
devtools::build_vignettes()
devtools::build()

which populates man/ when executed. Static site builders like pkgdown look in man/ to produce site files, however commands like the following allow for a quick check of how .Rd files actually render.

R CMD Rdconv -t html man/make_projection.Rd > make_projections.html

For more information see the CRAN page on writing R extensions.

Vignettes

To build vignettes, we follow Wickham and use knitr, a markdown vignette engine. knitr is piloted by rmarkdown, which uses pandoc to convert between markdown and HTML. Note that pandoc is not an R library, check the pandoc page for installation instructions. For the minute, it seems like everything in the doc directory is built automatically based on the *.Rmd files in vignettes. Iterating through the build process a few more times should help clarify this.

Package website

We use the static site generator pkgdown as follows

library("pkgdown")
pkgdown::build_site()

This produces relevant text files in the docs/ directory. We commit this to the gh-pages branch to avoid polluting the main branch, which is reserved for source code.

R internals and C/C++

C and C++ extensions to R are often bound using the Rcpp package. Since our package is relatively simple, we avoid incurring the additional dependancy that Rcpp incurs, and instead perform bindings using the basic API that R provides for C/C++ extensions. Technically this binding is implemented in the header file Rinternals.h, with some additional material in Rdefine.h and R.h. The location of these is given by R RHOME, with the full paths on macOS being

/usr/local/Cellar/r/4.2.3/include/Rinternals.h
/usr/local/Cellar/r/4.2.3/include/Rdefines.h
/usr/local/Cellar/r/4.2.3/include/R.h

Some helpful resources for learning the basics of the R API for C are given below.

Resources

I found the following resources to be most helpful in learning R’s C API

  • a gentle overview by Hadley Wickham
  • the authoritative R internals manual by the core R team
  • the above has been parsed and simplified in R internals by Hadley Wickham

In addition these blogs by Jonathan Callahan helped me in the very beginning. An overview of the C interface can be found here and here, and a packaging walkthrough here.

Resources

In addition to the CRAN home page, which contains a handful of incredibly useful manuals (under the Documentation section), I have found the following to be helpful

  • the section Writing R extensions in the CRAN documentation is an absolute must read. However, there’s a steep learning curve if you’re not yet familiar with R’s API for C
  • R packages by Hadley Wickham is an excellent guide to packaging best practice, and is much more readable than hardcore CRAN documentation
  • indeed anything about R development by Hadley Wickham I would strongly recommend, he seems to be one of the stars of the R community
  • the so-called tidyverse suite of packages demonstrates R best practice in my opinion. There are plenty of beautiful packages in there on which we can model ours. Several include sophisticated C and C++ source libraries (Hadley Wickham is involved in a bunch of these. Incidentally, it would be wonderful if he is available for code review. Can funding be allocated for this kind of thing?)
  • see the resources in the section above on R internals
  • Hadley Wickham has an R style guide that would be good to follow