├── .Rbuildignore ├── .Rprofile ├── .gitignore ├── .jupyter └── jupyter_notebook_config.py ├── .travis.sh ├── .travis.yml ├── DESCRIPTION ├── Example_Rmd.Rmd ├── LICENSE ├── R-in-Jupyter-Example.ipynb ├── README.md ├── binder ├── install.R ├── postBuild ├── requirements.txt ├── runtime.txt └── trigger_binder.sh ├── packrat ├── init.R ├── packrat.lock └── packrat.opts └── tests └── test_notebooks.py /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^packrat/ 2 | ^\.Rprofile$ 3 | -------------------------------------------------------------------------------- /.Rprofile: -------------------------------------------------------------------------------- 1 | #### -- Packrat Autoloader (version 0.5.0) -- #### 2 | source("packrat/init.R") 3 | #### -- End Packrat Autoloader -- #### 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | 8 | # Example code in package build process 9 | *-Ex.R 10 | 11 | # Output files from R CMD build 12 | /*.tar.gz 13 | 14 | # Output files from R CMD check 15 | /*.Rcheck/ 16 | 17 | # RStudio files 18 | .Rproj.user/ 19 | 20 | # produced vignettes 21 | vignettes/*.html 22 | vignettes/*.pdf 23 | 24 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 25 | .httr-oauth 26 | 27 | # knitr and R markdown default cache directories 28 | /*_cache/ 29 | /cache/ 30 | 31 | # Temporary files created by R markdown 32 | *.utf8.md 33 | *.knit.md 34 | 35 | # Shiny token, see https://shiny.rstudio.com/articles/shinyapps.html 36 | rsconnect/ 37 | 38 | *.bak 39 | .ipynb_checkpoints 40 | *__pycache__ 41 | 42 | # Packrat 43 | packrat/lib*/ 44 | packrat/src 45 | -------------------------------------------------------------------------------- /.jupyter/jupyter_notebook_config.py: -------------------------------------------------------------------------------- 1 | c.NotebookApp.contents_manager_class = "jupytext.TextFileContentsManager" 2 | -------------------------------------------------------------------------------- /.travis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copied from the IRkernel repo 4 | # https://github.com/IRkernel/IRkernel/blob/master/.travis.sh 5 | 6 | create_conda_environment() ( 7 | set -ex 8 | 9 | # http://conda.pydata.org/docs/travis.html 10 | wget "https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh" -O miniconda.sh 11 | bash miniconda.sh -b -p "$HOME/miniconda" 12 | rm miniconda.sh # needed to prevent a error in the R CMD check part 13 | 14 | hash -r 15 | conda config --set always_yes yes --set changeps1 no 16 | conda update -q conda 17 | # Useful for debugging any issues with conda 18 | conda info -a 19 | conda create -q -n test-environment python=3.6 pip jupyter pytest 20 | 21 | ls ~/miniconda/bin 22 | ) 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: R 2 | sudo: false 3 | dist: trusty 4 | cache: packages 5 | r_packages: 6 | - devtools 7 | r_github_packages: 8 | - IRkernel/IRkernel 9 | - nteract/papermillr 10 | before_script: 11 | - source .travis.sh 12 | - export PATH="$HOME/miniconda/bin:$PATH" 13 | - create_conda_environment 14 | - source activate test-environment 15 | - pip install -U -q pip setuptools wheel 16 | - pip install -U -q 'papermill>=0.16.0' 17 | - R -e "IRkernel::installspec()" 18 | - jupyter kernelspec list 19 | - pip freeze 20 | script: 21 | # Run pytest -s to disable capturing of stdout and see prints 22 | - pytest 23 | 24 | stages: 25 | - test 26 | - name: binder 27 | if: (branch = master) AND (NOT (type IN (pull_request))) 28 | 29 | jobs: 30 | include: 31 | - r: release 32 | - stage: binder 33 | before_install: skip 34 | install: skip 35 | before_script: skip 36 | script: 37 | # Use Binder build API to trigger repo2docker to build image 38 | - bash binder/trigger_binder.sh https://mybinder.org/build/gh/matthewfeickert/R-in-Jupyter-with-Binder/"${TRAVIS_BRANCH}" 39 | after_success: skip 40 | 41 | env: 42 | global: 43 | - MAKEFLAGS="-j 2" 44 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: rjupyterbinder 2 | Title: Example of how to use R in Jupyter notebooks and make compatible with Binder 3 | Version: 0.0.1 4 | Authors@R: person("Matthew", "Feickert", email = "matthewfeickert@users.noreply.github.com", 5 | role = c("aut", "cre")) 6 | Description: Example of how to use R in Jupyter notebooks and make compatible with Binder. 7 | License: BSD 3-Clause 8 | LazyData: true 9 | URL: https://github.com/matthewfeickert/R-in-Jupyter-with-Binder 10 | BugReports: https://github.com/matthewfeickert/R-in-Jupyter-with-Binder/issues 11 | Depends: 12 | R (>= 3.1.0) 13 | Imports: ggplot2 14 | Suggests: 15 | testthat (>= 0.7), 16 | devtools, 17 | packrat 18 | Encoding: UTF-8 19 | -------------------------------------------------------------------------------- /Example_Rmd.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Example R Markdown Notebook" 3 | output: 4 | html_document: 5 | df_print: paged 6 | jupyter: 7 | kernelspec: 8 | display_name: R 9 | language: R 10 | name: ir 11 | language_info: 12 | codemirror_mode: r 13 | file_extension: .r 14 | mimetype: text/x-r-source 15 | name: R 16 | pygments_lexer: r 17 | version: 3.4.3 18 | --- 19 | 20 | This is a [R Markdown](http://rmarkdown.rstudio.com) document (written in 100% valid R Markdown). You can render this in RStudio with "Knit" ([the API to `rmarkdown::render`](https://rmarkdown.rstudio.com/authoring_quick_tour.html#rendering_output)). However, if you are viewing this on Binder you are viewing it as a Jupyter Notebook(!). That means that you also are able to interact with it as you normally would in Jupyter. When you execute code within the notebook, the results appear beneath the code. 21 | 22 | As an example, run the cell below, which is taken from [the R Markdown website](https://rmarkdown.rstudio.com/authoring_quick_tour.html#r_code_chunks) 23 | 24 | ```{r qplot, fig.width=4, fig.height=3, message=FALSE} 25 | # quick summary and plot 26 | library(ggplot2) 27 | summary(cars) 28 | qplot(speed, dist, data=cars) + geom_smooth() 29 | ``` 30 | 31 | Enjoy the ability to work in both R Markdown and in the Jupyter ecosystem! 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Matthew Feickert 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # R in Jupyter with Binder 2 | 3 | An example of how to use R in Jupyter notebooks and then make a Binder environment to run them interactively on the web. 4 | This repo was inspired from [a Tweet](https://twitter.com/Alex_Danvers/status/1016395766250627072) in a discussion about [Episode 7 of The Bayes Factor podcast](https://sites.tufts.edu/hilab/podcast/liz-page-gould-and-alex-danvers/). 5 | 6 | > Disclaimer: I am a physicist and primarily a Python and C++ programmer and I don't use/know R. This repo is just what I know from being able to read code and understanding how Jupyter works. 7 | 8 | [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 9 | [![DOI](https://zenodo.org/badge/140347900.svg)](https://zenodo.org/badge/latestdoi/140347900) 10 | [![Build Status](https://travis-ci.com/matthewfeickert/R-in-Jupyter-with-Binder.svg?branch=master)](https://travis-ci.com/matthewfeickert/R-in-Jupyter-with-Binder) 11 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/matthewfeickert/R-in-Jupyter-with-Binder/master?filepath=R-in-Jupyter-Example.ipynb) 12 | 13 | ## Check it out first 14 | 15 | Before learning how to setup R in Jupyter, first go check out how cool it is in Binder! Just click the "launch Binder" badge above. 16 | 17 | ## Table of contents 18 | 19 | - [Requirements](#requirements) 20 | - [Setup and Installation](#setup-and-installation) 21 | - [Enable package dependency management with packrat](#enable-package-dependency-management-with-packrat) 22 | - [Using papermill with Jupyter](#using-papermill-with-jupyter) 23 | - [Testing Jupyter notebooks with pytest](#testing-jupyter-notebooks-with-pytest) 24 | - [Automating testing alongside development with CI](#automating-testing-alongside-development-with-ci) 25 | - [Setting up a Binder environment](#setting-up-a-binder-environment) 26 | - [Preservation and DOI with Zenodo](#preservation-and-doi-with-zenodo) 27 | - [R Markdown in Jupyter with jupytext](#r-markdown-in-jupyter-with-jupytext) 28 | - [Further Reading and Resources](#further-reading-and-resources) 29 | - [Acknowledgements](#acknowledgements) 30 | 31 | ## Requirements 32 | 33 | Before you can begin you need to make sure that you have the following in your working environment 34 | - [Jupyter](http://jupyter.org/) 35 | - A modern version of [R](https://www.r-project.org/) 36 | 37 | ## Setup and Installation 38 | 39 | - [Install Jupyter](http://jupyter.org/install) 40 | - If you aren't familiar with Python and `pip` then just follow the instructions for installing with Anaconda 41 | - [Install R](https://cran.r-project.org/doc/manuals/r-release/R-admin.html) 42 | - Install the [R kernel for Jupyter](https://github.com/IRkernel/IRkernel) ([IRkernel](https://irkernel.github.io/)) 43 | 44 | ## Enable package dependency management with [packrat](https://github.com/rstudio/packrat) 45 | 46 | The first step in any project should be making sure that the library dependencies are specified and reproducible. This can be done in R with the [packrat](https://rstudio.github.io/packrat/) library. 47 | 48 | First install packrat 49 | 50 | ```shell 51 | R -e 'install.packages("packrat")' 52 | ``` 53 | 54 | Then from your project directory initialize Packrat for your project 55 | 56 | ```shell 57 | R -e 'packrat::init()' 58 | ``` 59 | 60 | which will determine the R libraries used in your project and then build the list of dependencies for you. This effectively creates an isolated computing environment (known as "virtual environments" it other programming languages). 61 | 62 | Running `packrat::init()` results in the directory `packrat` being created with the files `init.R`, `packrat.lock` and `packrat.opts` inside of it. It will additionally also create or edit a project `.Rprofile` and edit any existing `.gitignore` file. The following files should be kept under version control for your project to be reproducible anywhere: 63 | 64 | - `.Rprofile` 65 | - `packrat/init.R` 66 | - `packrat/packrat.lock` 67 | - `packrat/packrat.opts` 68 | 69 | As you work on your project and use more libraries you can [update your dependencies managed by `packrat`](https://rstudio.github.io/packrat/walkthrough.html) with (inside the R environment) 70 | 71 | ```r 72 | packrat::snapshot() 73 | ``` 74 | 75 | which updates `packrat/packrat.lock` and `packrat/packrat.opts`. You can also check if you have introduces new dependencies with 76 | 77 | ```r 78 | packrat::status() 79 | ``` 80 | 81 | If you remove libraries from use that were managed by `packrat` you can check this with 82 | 83 | ```r 84 | packrat::status() 85 | ``` 86 | 87 | and then remove them from `packrat` with 88 | 89 | ```r 90 | packrat::clean() 91 | ``` 92 | 93 | to ensure the minimal environment necessary for reproducibility is kept. Checking the status should now show 94 | 95 | ```r 96 | packrat::status() 97 | #> Up to date. 98 | ``` 99 | 100 | If you have a `packrat.lock` file that you want to create an environment from that doesn't already exist you can build the environment by running (from the command line) 101 | 102 | ```shell 103 | R -e 'packrat::restore()' 104 | ``` 105 | 106 | This is one way in which you could setup the same `packrat` environment on a different machine from the Git repository. 107 | 108 | ## Using [papermill](https://github.com/nteract/papermill) with Jupyter 109 | 110 | > Papermill is a tool for parameterizing, executing, and analyzing Jupyter Notebooks. 111 | 112 | This means that you can use [papermill](https://github.com/nteract/papermill) to _externally_ run, manipulate, and test Jupyter notebooks. This allows you to use Jupyter notebooks as components of an automated data analysis pipeline or for procedurally testing variations. 113 | 114 | - To use with Jupyter notebooks running in the IRkernel [install the R bindings for papermill (`papermillR`)](https://github.com/nteract/papermillr) 115 | 116 | A toy example of how to use papermill is demonstrated in the [example Jupyter notebook](https://github.com/matthewfeickert/R-in-Jupyter-with-Binder/blob/master/R-in-Jupyter-Example.ipynb). 117 | 118 | ## Testing Jupyter notebooks with [pytest](https://docs.pytest.org/en/latest/) 119 | 120 | To provide testing for Jupyter notebooks we can use [pytest](https://docs.pytest.org/en/latest/) in combination with papermill. 121 | 122 | - [Install pytest](https://docs.pytest.org/en/latest/getting-started.html) 123 | - If you installed Jupyter with Conda then you can also [install pytest with Conda](https://anaconda.org/anaconda/pytest) 124 | 125 | Once you have installed pytest and done some [minimal reading of the docs](https://docs.pytest.org/en/latest/getting-started.html#create-your-first-test) then create a `tests` directory and write your test files in Python inside of it. 126 | 127 | An example of some very simple tests using papermill is provided in [`tests/test_notebooks.py`](https://github.com/matthewfeickert/R-in-Jupyter-with-Binder/blob/master/tests/test_notebooks.py). Once you read though and understand what the testing file is doing execute the tests with `pytest` in the top level directory of the repo by running 128 | 129 | ```shell 130 | pytest 131 | ``` 132 | 133 | To see the output that the individual testing functions would normally [print to `stdout`](https://docs.pytest.org/en/latest/capture.html) run with the `-s` flag 134 | 135 | ```shell 136 | pytest -s 137 | ``` 138 | 139 | ### Why write tests? 140 | 141 | There are numerous reasons to test your code, but as a scientist an obvious one is ensured reproducibility of experimental results. If your analysis code has unit tests and the analysis itself exists in an automatically testable pipeline then you and your colleagues should have more confidence in your analysis. Additionally, your analysis becomes (by necessity) a well documented and transparent process. 142 | 143 | Want to learn more? Check out the [Test and Code podcast](http://testandcode.com/) hosted by [Brian Okken](https://github.com/okken). 144 | 145 | ### Why test with pytest? 146 | 147 | pytest is the most comprehensive and scalable testing framework that I know of. I am biased, but I continue to be impressed with how nimble, powerful, and easy it is to work with. It makes me want to write tests. For the purposes of this demo repository it is also important as it allows for writing tests that use papermill (papermill's `execute_notebook` is only accessible through the [Python API](http://papermill.readthedocs.io/en/latest/usage.html#execute-via-the-python-api)). 148 | 149 | There are testing frameworks in R, most notably [testthat](https://github.com/r-lib/testthat), which I assume are good. So I would encourage you to explore those as well. 150 | 151 | ## Automating testing alongside development with CI 152 | 153 | Assuming that you're using Git to develop your analysis code then you can have a continuous integration service (such as [Travis CI](https://travis-ci.org/) or [CircleCI](https://circleci.com/)) automatically test your code in a fresh environment every time you push to GitHub. Testing with CI is a great way to know that your analysis code is working exactly as expected in a reproducible environment from installation all the way through execution as you develop, revise, and improve it. To see the output of the build/install and testing of this repo in Travis click on the build status badge at the top of the `README` (also here: [![Build Status](https://travis-ci.com/matthewfeickert/R-in-Jupyter-with-Binder.svg?branch=master)](https://travis-ci.com/matthewfeickert/R-in-Jupyter-with-Binder)). 154 | 155 | To start off with I would recommend using Travis CI (it is the easiest to get up and running). 156 | 157 | - [Getting started with Travis CI](https://docs.travis-ci.com/user/getting-started/) 158 | - Example [`.travis.yml`](https://github.com/matthewfeickert/R-in-Jupyter-with-Binder/blob/master/.travis.yml) in this repo 159 | - [Travis CI docs on writing YAML CI files for R](https://docs.travis-ci.com/user/languages/r/) 160 | 161 | ### Access restrictions and hosting 162 | 163 | There may be instances where you want to have your Git repository be private until work is complete or other information is made publicly available, and you still want to be able to use CI services. 164 | 165 | Travis CI (currently) only works with GitHub and is [free only for public repositories](https://travis-ci.com/plans). CircleCI works with any Git web hosting service (i.e., GitHub, GitLab, Bitbucket) and allows for free use with public and private repositories [up to a monthly use time budget](https://circleci.com/pricing/). 166 | Additionally, GitLab offers [their own CI service](https://docs.gitlab.com/ee/ci/README.html) that is integrated into the GitLab platform. If your organization self-hosts an instance of GitLab (GitLab is [open core](https://about.gitlab.com/pricing/)) then you can use those CI tools with your private GitLab hosted repositories. If your organization has access to the enterprise version of GitLab then you can even run [GitLab CI on GitHub hosted repositories](https://docs.gitlab.com/ee/ci/ci_cd_for_external_repos/github_integration.html). 167 | 168 | ## Setting up a [Binder](https://mybinder.org/) environment 169 | 170 | [Binder](https://mybinder.org/) turns your GitHub repository into a fully interactive computational environment (as you hopefully have already seen from the demo notebook). It then allows people to run any code that exists in the repository from their web browser without having to install any code and is a great tool for collaboration and sharing results. 171 | 172 | The Binder team has done amazing work to make "Binderizing" a GitHub repository as simple as possible. In the case of getting an R computing environment many times all that you need (in addition to a `DESCRIPTION` file and maybe an `install.R`) is a `runtime.txt` file that dictates which daily snapshot of [MRAN](https://mran.microsoft.com/documents/rro/reproducibility) to use. See the [`binder`](https://github.com/matthewfeickert/R-in-Jupyter-with-Binder/tree/master/binder) directory for an example of what is needed to get this repository to run in Binder. 173 | 174 | - [Specifying an R environment with a runtime.txt file](https://mybinder.readthedocs.io/en/latest/sample_repos.html#specifying-an-r-environment-with-a-runtime-txt-file) 175 | - Example Jupyter+R environment on Binder: [![Binder](http://mybinder.org/badge_logo.svg)](http://mybinder.org/v2/gh/binder-examples/r/master?filepath=index.ipynb) 176 | - [Binder FAQs](https://mybinder.readthedocs.io/en/latest/faq.html) 177 | 178 | You'll note that the "launch Binder" badge at the top of the `README` automatically launches into the `R-in-Jupyter-Example.ipynb` notebook. This was configured to do so, but the default Binder behavior is to launch the Jupyter server and then show the directory structure of the repository. 179 | 180 | To see that behavior launch Binder from here: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/matthewfeickert/R-in-Jupyter-with-Binder/master) 181 | 182 | Once the server loads click on any file to open it in an editor or as a Jupyter notebook. 183 | 184 | ## Preservation and DOI with [Zenodo](https://zenodo.org/) 185 | 186 | To further make your analysis code more robust you can preserve it and make it [citable by getting a DOI](https://guides.github.com/activities/citable-code/) for the project repository with [Zenodo](https://zenodo.org/). Activating version tracking on your GitHub repository with Zenodo will allow it to automatically freeze a version of the repository with each new version tag and then archive it. Additionally, Zenodo will create a DOI for your project and versioned DOIs for the project releases which can be added as a DOI badge. This makes it trivial for others to cite your work and allows you to indicate what version of your code was used in any publications. 187 | 188 | ## R Markdown in Jupyter with [jupytext](https://github.com/mwouts/jupytext) 189 | 190 | [R Markdown](https://rmarkdown.rstudio.com/) is a very popular way to present beautifully rendered R along Markdown in different forms of documents. However, it is source only and not dynamically interactive as the R and Markdown needed to be [rendered together with Pandoc](https://stackoverflow.com/questions/40563479/relationship-between-r-markdown-knitr-pandoc-and-bookdown) ([Pandoc](https://pandoc.org/) is awesome). 191 | > [jupytext](https://github.com/mwouts/jupytext) is a utility to open and run R markdown notebooks in Jupyter and save Jupyter notebooks as R markdown. 192 | 193 | - [Install jupytext](https://github.com/mwouts/jupytext#installation) 194 | 195 | Once you have installed jupytext create a Jupyter config with 196 | 197 | ```shell 198 | jupyter notebook --generate-config 199 | ``` 200 | 201 | which creates the config file at 202 | 203 | ``` 204 | .jupyter/jupyter_notebook_config.py 205 | ``` 206 | 207 | Add the following line to the Jupyter config 208 | 209 | ```python 210 | c.NotebookApp.contents_manager_class = "jupytext.TextFileContentsManager" 211 | ``` 212 | 213 | If you now launch a Jupyter notebook server and open a `.Rmd` file the R Markdown should now be rendered in the interactive environment of Jupyter! 214 | 215 | ### R Markdown in Jupyter in Binder 216 | 217 | To get R Markdown working in Binder simple create a [`requirements.txt`](https://github.com/matthewfeickert/R-in-Jupyter-with-Binder/blob/master/binder/requirements.txt) file in the `binder` directory and add `jupytext` to it. Binder should take care of the rest! 218 | 219 | - Here's a minimal example using the [`Example_Rmd.Rmd`](https://github.com/matthewfeickert/R-in-Jupyter-with-Binder/blob/master/Example_Rmd.Rmd) file from this repository: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/matthewfeickert/R-in-Jupyter-with-Binder/master?filepath=Example_Rmd.Rmd) 220 | 221 | ## Further Reading and Resources 222 | 223 | - [Jupyter And R Markdown: Notebooks With R](https://www.datacamp.com/community/blog/jupyter-notebook-r), by [Karlijn Willems](https://github.com/Kacawi) 224 | - [Rocker](https://www.rocker-project.org/)'s [R configurations for Docker repo](https://github.com/rocker-org/rocker) 225 | - [Noam Ross](https://github.com/noamross), "[Docker for the UseR](https://github.com/noamross/nyhackr-docker-talk)", [New York Open Statistical Programming Meetup (nyhackr)](https://nyhackr.org/) (July 11th, 2018) 226 | - [rOpenSci](https://ropensci.org/) 227 | 228 | ## Acknowledgements 229 | 230 | - The [Jupyter and Binder team](https://github.com/orgs/jupyterhub/people) for making amazing open source software 231 | - [Marc Wouts](https://github.com/mwouts) for creating [jupytext](https://github.com/mwouts/jupytext) 232 | - [Achintya Rao](https://github.com/RaoOfPhysics) for insightful feedback, thoughtful discussion, and excellent ideas 233 | -------------------------------------------------------------------------------- /binder/install.R: -------------------------------------------------------------------------------- 1 | # Just need ggplot2 for example, but allows for further play 2 | # install.packages('tidyverse') 3 | install.packages("ggplot2") 4 | install.packages("dplyr") 5 | install.packages("tidyr") 6 | install.packages("readr") 7 | install.packages("purrr") 8 | install.packages("tibble") 9 | install.packages("stringr") 10 | install.packages("forcats") 11 | 12 | devtools::install_github("nteract/papermillr") 13 | -------------------------------------------------------------------------------- /binder/postBuild: -------------------------------------------------------------------------------- 1 | # It is easier to have Binder ignore packrat then do packrat::restore() 2 | # Though this does require manually running install.R 3 | rm .Rprofile 4 | Rscript binder/install.R 5 | -------------------------------------------------------------------------------- /binder/requirements.txt: -------------------------------------------------------------------------------- 1 | jupytext 2 | -------------------------------------------------------------------------------- /binder/runtime.txt: -------------------------------------------------------------------------------- 1 | r-2019-02-01 2 | -------------------------------------------------------------------------------- /binder/trigger_binder.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function trigger_binder() { 4 | local URL="${1}" 5 | 6 | curl --connect-timeout 10 --max-time 30 "${URL}" 7 | curl_return=$? 8 | 9 | # Return code 28 is when the --max-time is reached 10 | if [ "${curl_return}" -eq 0 ] || [ "${curl_return}" -eq 28 ]; then 11 | if [[ "${curl_return}" -eq 28 ]]; then 12 | printf "\nBinder build started.\nCheck back soon.\n" 13 | fi 14 | else 15 | return "${curl_return}" 16 | fi 17 | 18 | return 0 19 | } 20 | 21 | function main() { 22 | # 1: the Binder build API URL to curl 23 | trigger_binder $1 24 | } 25 | 26 | main "$@" || exit 1 27 | -------------------------------------------------------------------------------- /packrat/init.R: -------------------------------------------------------------------------------- 1 | local({ 2 | 3 | ## Helper function to get the path to the library directory for a 4 | ## given packrat project. 5 | getPackratLibDir <- function(projDir = NULL) { 6 | path <- file.path("packrat", "lib", R.version$platform, getRversion()) 7 | 8 | if (!is.null(projDir)) { 9 | 10 | ## Strip trailing slashes if necessary 11 | projDir <- sub("/+$", "", projDir) 12 | 13 | ## Only prepend path if different from current working dir 14 | if (!identical(normalizePath(projDir), normalizePath(getwd()))) 15 | path <- file.path(projDir, path) 16 | } 17 | 18 | path 19 | } 20 | 21 | ## Ensure that we set the packrat library directory relative to the 22 | ## project directory. Normally, this should be the working directory, 23 | ## but we also use '.rs.getProjectDirectory()' if necessary (e.g. we're 24 | ## rebuilding a project while within a separate directory) 25 | libDir <- if (exists(".rs.getProjectDirectory")) 26 | getPackratLibDir(.rs.getProjectDirectory()) 27 | else 28 | getPackratLibDir() 29 | 30 | ## Unload packrat in case it's loaded -- this ensures packrat _must_ be 31 | ## loaded from the private library. Note that `requireNamespace` will 32 | ## succeed if the package is already loaded, regardless of lib.loc! 33 | if ("packrat" %in% loadedNamespaces()) 34 | try(unloadNamespace("packrat"), silent = TRUE) 35 | 36 | if (suppressWarnings(requireNamespace("packrat", quietly = TRUE, lib.loc = libDir))) { 37 | 38 | # Check 'print.banner.on.startup' -- when NA and RStudio, don't print 39 | print.banner <- packrat::get_opts("print.banner.on.startup") 40 | if (print.banner == "auto" && is.na(Sys.getenv("RSTUDIO", unset = NA))) { 41 | print.banner <- TRUE 42 | } else { 43 | print.banner <- FALSE 44 | } 45 | return(packrat::on(print.banner = print.banner)) 46 | } 47 | 48 | ## Escape hatch to allow RStudio to handle bootstrapping. This 49 | ## enables RStudio to provide print output when automagically 50 | ## restoring a project from a bundle on load. 51 | if (!is.na(Sys.getenv("RSTUDIO", unset = NA)) && 52 | is.na(Sys.getenv("RSTUDIO_PACKRAT_BOOTSTRAP", unset = NA))) { 53 | Sys.setenv("RSTUDIO_PACKRAT_BOOTSTRAP" = "1") 54 | setHook("rstudio.sessionInit", function(...) { 55 | # Ensure that, on sourcing 'packrat/init.R', we are 56 | # within the project root directory 57 | if (exists(".rs.getProjectDirectory")) { 58 | owd <- getwd() 59 | setwd(.rs.getProjectDirectory()) 60 | on.exit(setwd(owd), add = TRUE) 61 | } 62 | source("packrat/init.R") 63 | }) 64 | return(invisible(NULL)) 65 | } 66 | 67 | ## Bootstrapping -- only performed in interactive contexts, 68 | ## or when explicitly asked for on the command line 69 | if (interactive() || "--bootstrap-packrat" %in% commandArgs(TRUE)) { 70 | 71 | needsRestore <- "--bootstrap-packrat" %in% commandArgs(TRUE) 72 | 73 | message("Packrat is not installed in the local library -- ", 74 | "attempting to bootstrap an installation...") 75 | 76 | ## We need utils for the following to succeed -- there are calls to functions 77 | ## in 'restore' that are contained within utils. utils gets loaded at the 78 | ## end of start-up anyhow, so this should be fine 79 | library("utils", character.only = TRUE) 80 | 81 | ## Install packrat into local project library 82 | packratSrcPath <- list.files(full.names = TRUE, 83 | file.path("packrat", "src", "packrat") 84 | ) 85 | 86 | ## No packrat tarballs available locally -- try some other means of installation 87 | if (!length(packratSrcPath)) { 88 | 89 | message("> No source tarball of packrat available locally") 90 | 91 | ## There are no packrat sources available -- try using a version of 92 | ## packrat installed in the user library to bootstrap 93 | if (requireNamespace("packrat", quietly = TRUE) && packageVersion("packrat") >= "0.2.0.99") { 94 | message("> Using user-library packrat (", 95 | packageVersion("packrat"), 96 | ") to bootstrap this project") 97 | } 98 | 99 | ## Couldn't find a user-local packrat -- try finding and using devtools 100 | ## to install 101 | else if (requireNamespace("devtools", quietly = TRUE)) { 102 | message("> Attempting to use devtools::install_github to install ", 103 | "a temporary version of packrat") 104 | library(stats) ## for setNames 105 | devtools::install_github("rstudio/packrat") 106 | } 107 | 108 | ## Try downloading packrat from CRAN if available 109 | else if ("packrat" %in% rownames(available.packages())) { 110 | message("> Installing packrat from CRAN") 111 | install.packages("packrat") 112 | } 113 | 114 | ## Fail -- couldn't find an appropriate means of installing packrat 115 | else { 116 | stop("Could not automatically bootstrap packrat -- try running ", 117 | "\"'install.packages('devtools'); devtools::install_github('rstudio/packrat')\"", 118 | "and restarting R to bootstrap packrat.") 119 | } 120 | 121 | # Restore the project, unload the temporary packrat, and load the private packrat 122 | if (needsRestore) 123 | packrat::restore(prompt = FALSE, restart = TRUE) 124 | 125 | ## This code path only reached if we didn't restart earlier 126 | unloadNamespace("packrat") 127 | requireNamespace("packrat", lib.loc = libDir, quietly = TRUE) 128 | return(packrat::on()) 129 | 130 | } 131 | 132 | ## Multiple packrat tarballs available locally -- try to choose one 133 | ## TODO: read lock file and infer most appropriate from there; low priority because 134 | ## after bootstrapping packrat a restore should do the right thing 135 | if (length(packratSrcPath) > 1) { 136 | warning("Multiple versions of packrat available in the source directory;", 137 | "using packrat source:\n- ", shQuote(packratSrcPath)) 138 | packratSrcPath <- packratSrcPath[[1]] 139 | } 140 | 141 | 142 | lib <- file.path("packrat", "lib", R.version$platform, getRversion()) 143 | if (!file.exists(lib)) { 144 | dir.create(lib, recursive = TRUE) 145 | } 146 | 147 | message("> Installing packrat into project private library:") 148 | message("- ", shQuote(lib)) 149 | 150 | surround <- function(x, with) { 151 | if (!length(x)) return(character()) 152 | paste0(with, x, with) 153 | } 154 | 155 | 156 | ## Invoke install.packages() in clean R session 157 | peq <- function(x, y) paste(x, y, sep = " = ") 158 | installArgs <- c( 159 | peq("pkgs", surround(packratSrcPath, with = "'")), 160 | peq("lib", surround(lib, with = "'")), 161 | peq("repos", "NULL"), 162 | peq("type", surround("source", with = "'")) 163 | ) 164 | 165 | fmt <- "utils::install.packages(%s)" 166 | installCmd <- sprintf(fmt, paste(installArgs, collapse = ", ")) 167 | 168 | ## Write script to file (avoid issues with command line quoting 169 | ## on R 3.4.3) 170 | installFile <- tempfile("packrat-bootstrap", fileext = ".R") 171 | writeLines(installCmd, con = installFile) 172 | on.exit(unlink(installFile), add = TRUE) 173 | 174 | fullCmd <- paste( 175 | surround(file.path(R.home("bin"), "R"), with = "\""), 176 | "--vanilla", 177 | "--slave", 178 | "-f", 179 | surround(installFile, with = "\"") 180 | ) 181 | system(fullCmd) 182 | 183 | ## Tag the installed packrat so we know it's managed by packrat 184 | ## TODO: should this be taking information from the lockfile? this is a bit awkward 185 | ## because we're taking an un-annotated packrat source tarball and simply assuming it's now 186 | ## an 'installed from source' version 187 | 188 | ## -- InstallAgent -- ## 189 | installAgent <- "InstallAgent: packrat 0.5.0" 190 | 191 | ## -- InstallSource -- ## 192 | installSource <- "InstallSource: source" 193 | 194 | packratDescPath <- file.path(lib, "packrat", "DESCRIPTION") 195 | DESCRIPTION <- readLines(packratDescPath) 196 | DESCRIPTION <- c(DESCRIPTION, installAgent, installSource) 197 | cat(DESCRIPTION, file = packratDescPath, sep = "\n") 198 | 199 | # Otherwise, continue on as normal 200 | message("> Attaching packrat") 201 | library("packrat", character.only = TRUE, lib.loc = lib) 202 | 203 | message("> Restoring library") 204 | if (needsRestore) 205 | packrat::restore(prompt = FALSE, restart = FALSE) 206 | 207 | # If the environment allows us to restart, do so with a call to restore 208 | restart <- getOption("restart") 209 | if (!is.null(restart)) { 210 | message("> Packrat bootstrap successfully completed. ", 211 | "Restarting R and entering packrat mode...") 212 | return(restart()) 213 | } 214 | 215 | # Callers (source-erers) can define this hidden variable to make sure we don't enter packrat mode 216 | # Primarily useful for testing 217 | if (!exists(".__DONT_ENTER_PACKRAT_MODE__.") && interactive()) { 218 | message("> Packrat bootstrap successfully completed. Entering packrat mode...") 219 | packrat::on() 220 | } 221 | 222 | Sys.unsetenv("RSTUDIO_PACKRAT_BOOTSTRAP") 223 | 224 | } 225 | 226 | }) 227 | -------------------------------------------------------------------------------- /packrat/packrat.lock: -------------------------------------------------------------------------------- 1 | PackratFormat: 1.4 2 | PackratVersion: 0.5.0 3 | RVersion: 3.4.4 4 | Repos: CRAN=https://cloud.r-project.org 5 | 6 | Package: R6 7 | Source: CRAN 8 | Version: 2.3.0 9 | Hash: 8eccabbf292b5aba632985cde6406fc3 10 | 11 | Package: RColorBrewer 12 | Source: CRAN 13 | Version: 1.1-2 14 | Hash: c0d56cd15034f395874c870141870c25 15 | 16 | Package: Rcpp 17 | Source: CRAN 18 | Version: 0.12.19 19 | Hash: fdff9c3aa69adac28cd5c45cd250c9da 20 | 21 | Package: askpass 22 | Source: CRAN 23 | Version: 1.1 24 | Hash: 6f6c430e3cd0dd7d48f447700f4d7e7f 25 | Requires: sys 26 | 27 | Package: assertthat 28 | Source: CRAN 29 | Version: 0.2.0 30 | Hash: e8805df54c65ac96d50235c44a82615c 31 | 32 | Package: backports 33 | Source: CRAN 34 | Version: 1.1.3 35 | Hash: a0b8191e6bd2fe71aadd4678bb8f3c98 36 | 37 | Package: callr 38 | Source: CRAN 39 | Version: 3.1.1 40 | Hash: 461cdebafe2c1cfc23ddc37527633185 41 | Requires: R6, processx 42 | 43 | Package: cli 44 | Source: CRAN 45 | Version: 1.0.0 46 | Hash: f4239f89feb7ddc65821e4514e9734ae 47 | Requires: assertthat, crayon 48 | 49 | Package: clipr 50 | Source: CRAN 51 | Version: 0.5.0 52 | Hash: 9d588163f9234a17c6ad03d148db999d 53 | 54 | Package: clisymbols 55 | Source: CRAN 56 | Version: 1.2.0 57 | Hash: a76a309884277a4fd8a5d741965fbef5 58 | 59 | Package: colorspace 60 | Source: CRAN 61 | Version: 1.3-2 62 | Hash: 0bf8618b585fa98eb23414cd3ab95118 63 | 64 | Package: crayon 65 | Source: CRAN 66 | Version: 1.3.4 67 | Hash: ff2840dd9b0d563fc80377a5a45510cd 68 | 69 | Package: curl 70 | Source: CRAN 71 | Version: 3.3 72 | Hash: b201f64e6e1469e8a3571c746ffa9059 73 | 74 | Package: desc 75 | Source: CRAN 76 | Version: 1.2.0 77 | Hash: a0a3ca939997679a52816bae4ed6aaae 78 | Requires: R6, assertthat, crayon, rprojroot 79 | 80 | Package: devtools 81 | Source: CRAN 82 | Version: 2.0.1 83 | Hash: 4da83470ae57bd2db0ac06e91b1d3a08 84 | Requires: callr, cli, digest, git2r, httr, jsonlite, memoise, pkgbuild, 85 | pkgload, rcmdcheck, remotes, rstudioapi, sessioninfo, usethis, 86 | withr 87 | 88 | Package: dichromat 89 | Source: CRAN 90 | Version: 2.0-0 91 | Hash: 08eed0c80510af29bb15f840ccfe37ce 92 | 93 | Package: digest 94 | Source: CRAN 95 | Version: 0.6.18 96 | Hash: 65f62365ec69ddd17230d2ffe891a6ab 97 | 98 | Package: fs 99 | Source: CRAN 100 | Version: 1.2.6 101 | Hash: 8ebaba45e83860e9575a002c84dc245a 102 | Requires: Rcpp 103 | 104 | Package: ggplot2 105 | Source: CRAN 106 | Version: 2.2.1 107 | Hash: 46e5cb78836848aa44655e577433f54b 108 | Requires: digest, gtable, lazyeval, plyr, reshape2, scales, tibble 109 | 110 | Package: gh 111 | Source: CRAN 112 | Version: 1.0.1 113 | Hash: 3f8812accd1320227d744bca620e8c42 114 | Requires: httr, ini, jsonlite 115 | 116 | Package: git2r 117 | Source: CRAN 118 | Version: 0.24.0 119 | Hash: c0f2721353aeed78bbc579bfeda4be40 120 | 121 | Package: glue 122 | Source: CRAN 123 | Version: 1.3.0 124 | Hash: 1fbde6dec830370be696eee8ef31c9e4 125 | 126 | Package: gtable 127 | Source: CRAN 128 | Version: 0.2.0 129 | Hash: cd78381a9d3fea966ac39bd0daaf5554 130 | 131 | Package: httr 132 | Source: CRAN 133 | Version: 1.4.0 134 | Hash: 62d62d3ffcc9a34411b6e35a813f72dd 135 | Requires: R6, curl, jsonlite, mime, openssl 136 | 137 | Package: ini 138 | Source: CRAN 139 | Version: 0.3.1 140 | Hash: 9d6de5178c1cedabfb24e7d2acc9a092 141 | 142 | Package: jsonlite 143 | Source: CRAN 144 | Version: 1.6 145 | Hash: 5f969e213e966135393e3e304abf3f49 146 | 147 | Package: labeling 148 | Source: CRAN 149 | Version: 0.3 150 | Hash: ecf589b42cd284b03a4beb9665482d3e 151 | 152 | Package: lazyeval 153 | Source: CRAN 154 | Version: 0.2.1 155 | Hash: 88926ad9c43581fd0822a37c8ed09f05 156 | 157 | Package: magrittr 158 | Source: CRAN 159 | Version: 1.5 160 | Hash: bdc4d48c3135e8f3b399536ddf160df4 161 | 162 | Package: memoise 163 | Source: CRAN 164 | Version: 1.1.0 165 | Hash: 410fcd334bc626db100237cc1370f2e9 166 | Requires: digest 167 | 168 | Package: mime 169 | Source: CRAN 170 | Version: 0.6 171 | Hash: 2ed8f98b8284ad733f3907fc6e2f1334 172 | 173 | Package: munsell 174 | Source: CRAN 175 | Version: 0.5.0 176 | Hash: 38d0efee9bb99bef143bde41c4ce715c 177 | Requires: colorspace 178 | 179 | Package: openssl 180 | Source: CRAN 181 | Version: 1.2.1 182 | Hash: c3c2751a977ed402ec7a2a32698fb533 183 | Requires: askpass 184 | 185 | Package: packrat 186 | Source: CRAN 187 | Version: 0.5.0 188 | Hash: 498643e765d1442ba7b1160a1df3abf9 189 | 190 | Package: pillar 191 | Source: CRAN 192 | Version: 1.2.3 193 | Hash: d3b1c0a6cf4b64212509130845c22e09 194 | Requires: cli, crayon, rlang, utf8 195 | 196 | Package: pkgbuild 197 | Source: CRAN 198 | Version: 1.0.2 199 | Hash: 770e918f4c389e4fef9a891d043bf84f 200 | Requires: R6, callr, cli, crayon, desc, prettyunits, rprojroot, withr 201 | 202 | Package: pkgload 203 | Source: CRAN 204 | Version: 1.0.2 205 | Hash: 41eb2db35be61f6f9e8864cf87a1ecb0 206 | Requires: desc, pkgbuild, rlang, rprojroot, rstudioapi, withr 207 | 208 | Package: plyr 209 | Source: CRAN 210 | Version: 1.8.4 211 | Hash: c58ebd9ae0d41ad128635787a2832698 212 | Requires: Rcpp 213 | 214 | Package: praise 215 | Source: CRAN 216 | Version: 1.0.0 217 | Hash: 77da8f1df873a4b91e5c4a68fe2fb1b6 218 | 219 | Package: prettyunits 220 | Source: CRAN 221 | Version: 1.0.2 222 | Hash: 49286102a855640daaa38eafe8b1ec30 223 | Requires: assertthat, magrittr 224 | 225 | Package: processx 226 | Source: CRAN 227 | Version: 3.2.1 228 | Hash: fdc6a66626b75f96ee28ffc770d9ebd7 229 | Requires: R6, ps 230 | 231 | Package: ps 232 | Source: CRAN 233 | Version: 1.3.0 234 | Hash: 1d4cae95887ffe5b1a22bea5994476cd 235 | 236 | Package: rcmdcheck 237 | Source: CRAN 238 | Version: 1.3.2 239 | Hash: 162a63e909423b7c5f44c30711135481 240 | Requires: R6, callr, cli, crayon, desc, digest, pkgbuild, prettyunits, 241 | rprojroot, sessioninfo, withr, xopen 242 | 243 | Package: remotes 244 | Source: CRAN 245 | Version: 2.0.2 246 | Hash: cfcf5e119ed5e6af4b47530ba59101f3 247 | 248 | Package: reshape2 249 | Source: CRAN 250 | Version: 1.4.3 251 | Hash: f50582f9059ab381cd38dd02697d8a88 252 | Requires: Rcpp, plyr, stringr 253 | 254 | Package: rlang 255 | Source: CRAN 256 | Version: 0.2.2 257 | Hash: 49b735b7b1d14f561d21cce12c6703df 258 | 259 | Package: rprojroot 260 | Source: CRAN 261 | Version: 1.3-2 262 | Hash: a25c3f70c166fb3fbabc410eb32b6366 263 | Requires: backports 264 | 265 | Package: rstudioapi 266 | Source: CRAN 267 | Version: 0.9.0 268 | Hash: e5e648a0944df6ea634d8173d09e236f 269 | 270 | Package: scales 271 | Source: CRAN 272 | Version: 0.5.0 273 | Hash: e2809ccef9c824f0cb81a1cddbe542c7 274 | Requires: R6, RColorBrewer, Rcpp, dichromat, labeling, munsell, plyr, 275 | viridisLite 276 | 277 | Package: sessioninfo 278 | Source: CRAN 279 | Version: 1.1.1 280 | Hash: 9e50c8458e611f166ba702277cbb5096 281 | Requires: cli, withr 282 | 283 | Package: stringi 284 | Source: CRAN 285 | Version: 1.2.3 286 | Hash: bccbb90bf5e1c53f659359c06c0dde79 287 | 288 | Package: stringr 289 | Source: CRAN 290 | Version: 1.3.1 291 | Hash: 9f417a1d899ed1f080942ab36998e8b5 292 | Requires: glue, magrittr, stringi 293 | 294 | Package: sys 295 | Source: CRAN 296 | Version: 2.1 297 | Hash: 5ce312d2f816b21f602cb81fe4659a0b 298 | 299 | Package: testthat 300 | Source: CRAN 301 | Version: 2.0.0 302 | Hash: 537114b476376c5773bf3c557f5bbd19 303 | Requires: R6, cli, crayon, digest, magrittr, praise, rlang, withr 304 | 305 | Package: tibble 306 | Source: CRAN 307 | Version: 1.4.2 308 | Hash: 83895360ce4f8d2ce92eee00526b5b0b 309 | Requires: cli, crayon, pillar, rlang 310 | 311 | Package: usethis 312 | Source: CRAN 313 | Version: 1.4.0 314 | Hash: bdf0ce7802818c5dfc592dd73d62db5b 315 | Requires: clipr, clisymbols, crayon, curl, desc, fs, gh, git2r, glue, 316 | rlang, rprojroot, rstudioapi, whisker 317 | 318 | Package: utf8 319 | Source: CRAN 320 | Version: 1.1.4 321 | Hash: f3f97ce59092abc8ed3fd098a59e236c 322 | 323 | Package: viridisLite 324 | Source: CRAN 325 | Version: 0.3.0 326 | Hash: 78bb072c4f9e729a283d4c40ec93f9c6 327 | 328 | Package: whisker 329 | Source: CRAN 330 | Version: 0.3-2 331 | Hash: 803d662762e532705c2c066a82d066e7 332 | 333 | Package: withr 334 | Source: CRAN 335 | Version: 2.1.2 336 | Hash: d534108bcd5f34ec73e9eb523751ba20 337 | 338 | Package: xopen 339 | Source: CRAN 340 | Version: 1.0.0 341 | Hash: 22c2708f177f9fd9f8a52012bac61d6a 342 | Requires: processx 343 | -------------------------------------------------------------------------------- /packrat/packrat.opts: -------------------------------------------------------------------------------- 1 | auto.snapshot: FALSE 2 | use.cache: FALSE 3 | print.banner.on.startup: auto 4 | vcs.ignore.lib: TRUE 5 | vcs.ignore.src: FALSE 6 | external.packages: 7 | local.repos: 8 | load.external.packages.on.startup: TRUE 9 | ignored.packages: 10 | ignored.directories: 11 | data 12 | inst 13 | quiet.package.installation: TRUE 14 | snapshot.recommended.packages: FALSE 15 | snapshot.fields: 16 | Imports 17 | Depends 18 | LinkingTo 19 | symlink.system.packages: TRUE 20 | -------------------------------------------------------------------------------- /tests/test_notebooks.py: -------------------------------------------------------------------------------- 1 | import papermill as pm 2 | import pytest 3 | 4 | 5 | def test_notebooks_nominal(tmpdir): 6 | output_nb = tmpdir.join('output.ipynb') 7 | # to check kernel name run: 8 | # jupyter kernelspec list 9 | common_kwargs = { 10 | 'output_path': str(output_nb), 11 | 'kernel_name': 'ir' 12 | } 13 | 14 | pm.execute_notebook('R-in-Jupyter-Example.ipynb', **common_kwargs) 15 | 16 | nb = pm.read_notebook(str(output_nb)) 17 | print(nb.data) 18 | assert nb.data['coin_trials'] == pytest.approx(10.6667) 19 | 20 | 21 | def test_notebooks_alternative(tmpdir): 22 | output_nb = tmpdir.join('output.ipynb') 23 | common_kwargs = { 24 | 'output_path': str(output_nb), 25 | # 'kernel_name': 'python{}'.format(sys.version_info.major) 26 | 'kernel_name': 'ir' 27 | } 28 | 29 | pm.execute_notebook('R-in-Jupyter-Example.ipynb', 30 | parameters=dict(heads=2, tosses=8), 31 | **common_kwargs) 32 | nb = pm.read_notebook(str(output_nb)) 33 | print(nb.data) 34 | assert nb.data['coin_trials'] == pytest.approx(28.4444) 35 | --------------------------------------------------------------------------------