├── vignettes ├── .gitignore ├── osf-setup-images │ ├── 01.png │ ├── 02.png │ ├── 03.png │ ├── 04.png │ ├── 05.png │ ├── 06.png │ ├── 07.png │ ├── 08.png │ ├── 09.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 13.png │ ├── 14.png │ ├── 15.png │ ├── 16.png │ ├── 17.png │ ├── 18.png │ ├── 19.png │ ├── 20.png │ ├── 21.png │ ├── 22.png │ ├── 23.png │ ├── 24.png │ ├── 25.png │ ├── 26.png │ ├── 27.png │ ├── 28.png │ ├── 29.png │ └── 30.png └── osf-setup.Rmd ├── LICENSE ├── tests ├── testthat │ ├── test_use_circleci.R │ ├── test_use_dockerfile.R │ ├── test_use_analysis.R │ ├── helper-setup_temporary_package.R │ ├── test_use_travis.R │ ├── test_add_dependencies_to_description.R │ └── test_use_readme_rmd.R └── testthat.R ├── .gitignore ├── analysis ├── paper │ ├── paper.docx │ ├── references.bib │ └── paper.Rmd └── templates │ ├── template.docx │ ├── journal-of-archaeological-science.csl │ └── template.Rmd ├── inst ├── templates │ ├── thesis_template │ │ ├── figure │ │ │ ├── uw.png │ │ │ ├── uw-100px.png │ │ │ └── subdivision.pdf │ │ ├── _bookdown.yml │ │ ├── 04-conclusion.Rmd │ │ ├── 05-appendix.Rmd │ │ ├── 99-references.Rmd │ │ ├── 98-colophon.Rmd │ │ ├── chemarr.sty │ │ ├── inidex.Rmd │ │ ├── 02-chap2.Rmd │ │ ├── bib │ │ │ └── thesis.bib │ │ ├── template.tex │ │ ├── 01-chap1.Rmd │ │ └── 03-chap3.Rmd │ ├── word_templates │ │ ├── template.docx │ │ └── template.Rmd │ ├── vignette-yaml │ ├── circle.yml-without-docker-hub │ ├── readme-rmd-pre-commit.sh │ ├── circle.yml │ ├── circle.yml-with-docker-hub │ ├── Dockerfile │ ├── travis.yml-no-docker │ ├── journal-of-archaeological-science.csl │ ├── travis.yml-with-docker │ ├── references.bib │ ├── CONDUCT.md │ ├── omni-README │ ├── paper.Rmd │ └── CONTRIBUTING.md └── notes │ └── Workflow_summerschool.Rmd ├── .Rbuildignore ├── man ├── is.package.Rd ├── github_pat.Rd ├── use_git_quietly.Rd ├── as.package.Rd ├── check_dep_version.Rd ├── use_git.Rd ├── package_file.Rd ├── parse_deps.Rd ├── use_git_hook.Rd ├── add_dependencies_to_description.Rd ├── use_dockerfile.Rd ├── create_compendium.Rd ├── use_circleci.Rd ├── use_build_ignore.Rd ├── use_readme_rmd.Rd ├── use_compendium.Rd ├── use_github_links.Rd ├── use_analysis.Rd ├── use_travis.Rd └── use_github.Rd ├── rrtools.Rproj ├── circle.yml ├── Dockerfile ├── NAMESPACE ├── .travis.yml ├── LICENSE.md ├── R ├── zzz.R ├── package-deps.R ├── infrastructure.R ├── package.R ├── utils.R ├── github.R ├── manage_dependencies.R ├── git.R └── infrastructure-git.R ├── DESCRIPTION ├── CONDUCT.md ├── CONTRIBUTING.md ├── README.Rmd └── README.md /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2017 2 | COPYRIGHT HOLDER: Ben Marwick 3 | -------------------------------------------------------------------------------- /tests/testthat/test_use_circleci.R: -------------------------------------------------------------------------------- 1 | context("use_circleci()") -------------------------------------------------------------------------------- /tests/testthat/test_use_dockerfile.R: -------------------------------------------------------------------------------- 1 | context("use_dockerfile()") -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Meta 2 | doc 3 | inst/doc 4 | .Rproj.user 5 | .Rhistory 6 | .RData 7 | .Ruserdata 8 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(rrtools) 3 | 4 | test_check("rrtools") 5 | -------------------------------------------------------------------------------- /analysis/paper/paper.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/analysis/paper/paper.docx -------------------------------------------------------------------------------- /analysis/templates/template.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/analysis/templates/template.docx -------------------------------------------------------------------------------- /vignettes/osf-setup-images/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/01.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/02.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/03.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/04.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/05.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/06.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/07.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/08.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/09.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/10.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/11.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/12.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/13.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/14.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/15.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/16.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/17.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/18.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/19.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/20.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/21.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/22.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/23.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/24.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/25.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/26.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/27.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/28.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/29.png -------------------------------------------------------------------------------- /vignettes/osf-setup-images/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/vignettes/osf-setup-images/30.png -------------------------------------------------------------------------------- /inst/templates/thesis_template/figure/uw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/inst/templates/thesis_template/figure/uw.png -------------------------------------------------------------------------------- /inst/templates/word_templates/template.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/inst/templates/word_templates/template.docx -------------------------------------------------------------------------------- /inst/templates/thesis_template/figure/uw-100px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/inst/templates/thesis_template/figure/uw-100px.png -------------------------------------------------------------------------------- /inst/templates/thesis_template/figure/subdivision.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nevrome/rrtools/master/inst/templates/thesis_template/figure/subdivision.pdf -------------------------------------------------------------------------------- /inst/templates/vignette-yaml: -------------------------------------------------------------------------------- 1 | vignette: > 2 | %\VignetteIndexEntry{Vignette Title} 3 | %\VignetteEngine{knitr::rmarkdown} 4 | %\VignetteEncoding{UTF-8} 5 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^Meta$ 2 | ^doc$ 3 | ^.*\.Rproj$ 4 | ^\.Rproj\.user$ 5 | ^README\.Rmd$ 6 | ^README-.*\.png$ 7 | ^\.travis\.yml$ 8 | ^CONDUCT\.md$ 9 | ^Dockerfile$ 10 | ^analysis/ 11 | ^circle\.yml$ 12 | ^CONTRIBUTING\.md$ 13 | thesis 14 | ^LICENSE\.md$ 15 | -------------------------------------------------------------------------------- /man/is.package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/package.R 3 | \name{is.package} 4 | \alias{is.package} 5 | \title{Is the object a package?} 6 | \usage{ 7 | is.package(x) 8 | } 9 | \description{ 10 | Is the object a package? 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/_bookdown.yml: -------------------------------------------------------------------------------- 1 | book_filename: "thesis" 2 | chapter_name: "Chapter " 3 | rmd_files: ["index.Rmd", "01-chap1.Rmd", "02-chap2.Rmd", "03-chap3.Rmd", "04-conclusion.Rmd", "05-appendix.Rmd", "98-colophon.Rmd", "99-references.Rmd"] 4 | download: [["thesis.pdf", "PDF"], ["thesis.epub", "EPUB"], ["thesis.docx", "Word"]] 5 | -------------------------------------------------------------------------------- /inst/templates/circle.yml-without-docker-hub: -------------------------------------------------------------------------------- 1 | machine: 2 | services: 3 | - docker 4 | 5 | dependencies: 6 | override: 7 | - docker info 8 | - docker build -t $DOCKER_USER/{{{repo}}} . 9 | 10 | test: 11 | override: 12 | # see if we can start container... 13 | - docker run --name {{{repo}}} -d -p 8787:8787 $DOCKER_USER/{{{repo}}} 14 | 15 | -------------------------------------------------------------------------------- /man/github_pat.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/github.R 3 | \name{github_pat} 4 | \alias{github_pat} 5 | \title{Retrieve Github personal access token.} 6 | \usage{ 7 | github_pat(quiet = FALSE) 8 | } 9 | \description{ 10 | A github personal access token 11 | Looks in env var \code{GITHUB_PAT} 12 | } 13 | \keyword{internal} 14 | -------------------------------------------------------------------------------- /rrtools.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: XeLaTeX 14 | 15 | StripTrailingWhitespace: Yes 16 | 17 | BuildType: Package 18 | PackageUseDevtools: Yes 19 | PackageInstallArgs: --no-multiarch --with-keep.source 20 | PackageRoxygenize: rd,collate,namespace,vignette 21 | -------------------------------------------------------------------------------- /vignettes/osf-setup.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "How to use osf.io for release management and long term data storage?" 3 | author: "Ben Marwick & Clemens Schmid" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Vignette Title} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r, out.width = "400px"} 13 | knitr::include_graphics(list.files("osf-setup-images", full.names = TRUE)) 14 | ``` 15 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/04-conclusion.Rmd: -------------------------------------------------------------------------------- 1 | # Conclusion {-} 2 | 3 | If we don't want Conclusion to have a chapter number next to it, we can add the `{-}` attribute. 4 | 5 | **More info** 6 | 7 | And here's some other random info: the first paragraph after a chapter title or section head _shouldn't be_ indented, because indents are to tell the reader that you're starting a new paragraph. Since that's obvious after a chapter or section title, proper typesetting doesn't add an indent there. 8 | 9 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | services: 3 | - docker 4 | 5 | dependencies: 6 | override: 7 | - docker info 8 | - docker build -t $DOCKER_USER/rrtools . 9 | 10 | test: 11 | override: 12 | # see if we can start container... 13 | - docker run --name rrtools -d -p 8787:8787 $DOCKER_USER/rrtools 14 | 15 | deployment: 16 | hub: 17 | branch: master 18 | commands: 19 | - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS 20 | - docker push $DOCKER_USER/rrtools 21 | -------------------------------------------------------------------------------- /inst/templates/readme-rmd-pre-commit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | README=($(git diff --cached --name-only | grep -Ei '^README\.[R]?md$')) 3 | MSG="use 'git commit --no-verify' to override this check" 4 | 5 | if [[ ${#README[@]} == 0 ]]; then 6 | exit 0 7 | fi 8 | 9 | if [[ README.Rmd -nt README.md ]]; then 10 | echo -e "README.md is out of date; please re-knit README.Rmd\n$MSG" 11 | exit 1 12 | elif [[ ${#README[@]} -lt 2 ]]; then 13 | echo -e "README.Rmd and README.md should be both staged\n$MSG" 14 | exit 1 15 | fi 16 | -------------------------------------------------------------------------------- /inst/templates/circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | services: 3 | - docker 4 | 5 | dependencies: 6 | override: 7 | - docker info 8 | - docker build -t $DOCKER_USER/{{{repo}}} . 9 | 10 | test: 11 | override: 12 | # see if we can start container... 13 | - docker run --name {{{repo}}} -d -p 8787:8787 $DOCKER_USER/{{{repo}}} 14 | 15 | deployment: 16 | hub: 17 | branch: master 18 | commands: 19 | - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS 20 | - docker push $DOCKER_USER/{{{repo}}} 21 | -------------------------------------------------------------------------------- /inst/templates/circle.yml-with-docker-hub: -------------------------------------------------------------------------------- 1 | machine: 2 | services: 3 | - docker 4 | 5 | dependencies: 6 | override: 7 | - docker info 8 | - docker build -t $DOCKER_USER/{{{repo}}} . 9 | 10 | test: 11 | override: 12 | # see if we can start container... 13 | - docker run --name {{{repo}}} -d -p 8787:8787 $DOCKER_USER/{{{repo}}} 14 | 15 | deployment: 16 | hub: 17 | branch: master 18 | commands: 19 | - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS 20 | - docker push $DOCKER_USER/{{{repo}}} 21 | -------------------------------------------------------------------------------- /tests/testthat/test_use_analysis.R: -------------------------------------------------------------------------------- 1 | context("use_analysis()") 2 | 3 | #### run function #### 4 | 5 | suppressMessages( 6 | rrtools::use_analysis(pkg = package_path) 7 | ) 8 | 9 | #### check results #### 10 | 11 | test_that("use_analysis generates the template directories and files", { 12 | 13 | expect_equal(list.files(file.path(package_path, 'analysis')), 14 | c("data", "figures", "paper", "templates")) 15 | 16 | expect_equal(list.files(file.path(package_path, 'analysis', 'paper')), 17 | c("paper.Rmd", "references.bib")) 18 | 19 | }) 20 | -------------------------------------------------------------------------------- /man/use_git_quietly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/git.R 3 | \name{use_git_quietly} 4 | \alias{use_git_quietly} 5 | \title{Initialise a git repository without asking questions} 6 | \usage{ 7 | use_git_quietly(message = "Initial commit") 8 | } 9 | \arguments{ 10 | \item{message}{Message to use for first commit.} 11 | } 12 | \description{ 13 | `use_git_quietly()` initialises a Git repository and adds important files to 14 | `.gitignore`. If user consents, it also makes an initial commit. 15 | } 16 | \examples{ 17 | \dontrun{ 18 | use_git_quietly() 19 | } 20 | } 21 | \concept{git helpers} 22 | -------------------------------------------------------------------------------- /man/as.package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/package.R 3 | \name{as.package} 4 | \alias{as.package} 5 | \title{Coerce input to a package.} 6 | \usage{ 7 | as.package(x = NULL, create = NA) 8 | } 9 | \arguments{ 10 | \item{x}{object to coerce to a package} 11 | 12 | \item{create}{only relevant if a package structure does not exist yet: if 13 | \code{TRUE}, create a package structure; if \code{NA}, ask the user 14 | (in interactive mode only)} 15 | } 16 | \description{ 17 | Possible specifications of package: 18 | \itemize{ 19 | \item path 20 | \item package object 21 | } 22 | } 23 | \keyword{internal} 24 | -------------------------------------------------------------------------------- /man/check_dep_version.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/package-deps.R 3 | \name{check_dep_version} 4 | \alias{check_dep_version} 5 | \title{Check that the version of an imported package satisfies the requirements} 6 | \usage{ 7 | check_dep_version(dep_name, dep_ver = NA, dep_compare = NA) 8 | } 9 | \arguments{ 10 | \item{dep_name}{The name of the package with objects to import} 11 | 12 | \item{dep_ver}{The version of the package} 13 | 14 | \item{dep_compare}{The comparison operator to use to check the version} 15 | } 16 | \description{ 17 | Check that the version of an imported package satisfies the requirements 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/use_git.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/infrastructure-git.R 3 | \name{use_git} 4 | \alias{use_git} 5 | \title{Initialise a git repository.} 6 | \usage{ 7 | use_git(message = "Initial commit", pkg = ".") 8 | } 9 | \arguments{ 10 | \item{message}{Message to use for first commit.} 11 | 12 | \item{pkg}{Path to package. See \code{\link{as.package}} for more 13 | information.} 14 | } 15 | \description{ 16 | Initialise a git repository. 17 | } 18 | \examples{ 19 | \dontrun{use_git()} 20 | } 21 | \seealso{ 22 | Other git infrastructure: \code{\link{use_git_hook}}, 23 | \code{\link{use_github_links}}, \code{\link{use_github}} 24 | } 25 | \concept{git infrastructure} 26 | -------------------------------------------------------------------------------- /man/package_file.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/package.R 3 | \name{package_file} 4 | \alias{package_file} 5 | \title{Find file in a package.} 6 | \usage{ 7 | package_file(..., path = ".") 8 | } 9 | \arguments{ 10 | \item{...}{Components of the path.} 11 | 12 | \item{path}{Place to start search for package directory.} 13 | } 14 | \description{ 15 | It always starts by finding by walking up the path until it finds the 16 | root directory, i.e. a directory containing \code{DESCRIPTION}. If it 17 | cannot find the root directory, or it can't find the specified path, it 18 | will throw an error. 19 | } 20 | \examples{ 21 | \dontrun{ 22 | package_file("figures", "figure_1") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/testthat/helper-setup_temporary_package.R: -------------------------------------------------------------------------------- 1 | 2 | # This code runs before the tests. It creates a testpackage in 3 | # the temporary directory where all the functions of rrtools 4 | # can be applied safely and subsequently tested. 5 | 6 | # create temporary directory in file system 7 | playground_path <- paste0(tempdir(), "/testpackages") 8 | dir.create(playground_path, showWarnings = FALSE) 9 | 10 | # create test package 11 | package_path <- paste0( 12 | playground_path, 13 | tempfile(pattern = "testpackage.", tmpdir = "", fileext = "") 14 | ) 15 | 16 | rrtools:::quietly( 17 | rrtools::use_compendium( 18 | path = package_path, 19 | fields = getOption("devtools.desc"), 20 | rstudio = FALSE, 21 | open = FALSE, 22 | quiet = TRUE 23 | )) 24 | 25 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # get the base image, the rocker/verse has R, RStudio and pandoc 2 | FROM rocker/verse:3.4.3 3 | 4 | # required 5 | MAINTAINER Ben Marwick 6 | 7 | COPY . /rrtools 8 | 9 | # go into the repo directory 10 | RUN . /etc/environment \ 11 | 12 | # Install linux depedendencies here 13 | # e.g. need this for ggforce::geom_sina 14 | && sudo apt-get update \ 15 | && sudo apt-get install libudunits2-dev -y \ 16 | 17 | # build this compendium package 18 | && R -e "devtools::install('/rrtools', dep=TRUE)" \ 19 | 20 | # render the manuscript into a docx, you'll need to edit this if you've 21 | # customised the location and name of your main Rmd file 22 | && R -e "rmarkdown::render('/rrtools/analysis/paper/paper.Rmd')" 23 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/05-appendix.Rmd: -------------------------------------------------------------------------------- 1 | `r if(knitr:::is_latex_output()) '\\appendix'` 2 | 3 | `r if(!knitr:::is_latex_output()) '# (APPENDIX) Appendix {-}'` 4 | 5 | 8 | 9 | 10 | # The First Appendix 11 | 12 | This first appendix includes all of the R chunks of code that were hidden throughout the document (using the `include = FALSE` chunk tag) to help with readibility and/or setup. 13 | 14 | **In the main Rmd file** 15 | 16 | ```{r ref.label='include_packages', results='hide', echo = TRUE} 17 | ``` 18 | 19 | **In Chapter \@ref(ref-labels):** 20 | 21 | ```{r ref.label='include_packages_2', results='hide', echo = TRUE} 22 | ``` 23 | 24 | # The Second Appendix, for Fun 25 | -------------------------------------------------------------------------------- /man/parse_deps.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/package-deps.R 3 | \name{parse_deps} 4 | \alias{parse_deps} 5 | \title{Parse package dependency strings.} 6 | \usage{ 7 | parse_deps(string) 8 | } 9 | \arguments{ 10 | \item{string}{to parse. Should look like \code{"R (>= 3.0), ggplot2"} etc.} 11 | } 12 | \value{ 13 | list of two character vectors: \code{name} package names, 14 | and \code{version} package versions. If version is not specified, 15 | it will be stored as NA. 16 | } 17 | \description{ 18 | Parse package dependency strings. 19 | } 20 | \examples{ 21 | parse_deps("httr (< 2.1),\\nRCurl (>= 3)") 22 | # only package dependencies are returned 23 | parse_deps("utils (== 2.12.1),\\ntools,\\nR (>= 2.10),\\nmemoise") 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /inst/templates/Dockerfile: -------------------------------------------------------------------------------- 1 | # get the base image, the rocker/verse has R, RStudio and pandoc 2 | FROM rocker/{{{rocker}}}:{{{r_version}}} 3 | 4 | # required 5 | MAINTAINER Your Name 6 | 7 | COPY . /{{{repo}}} 8 | 9 | # go into the repo directory 10 | RUN . /etc/environment \ 11 | 12 | # Install linux depedendencies here 13 | # e.g. need this for ggforce::geom_sina 14 | && sudo apt-get update \ 15 | && sudo apt-get install libudunits2-dev -y \ 16 | 17 | # build this compendium package 18 | && R -e "devtools::install('/{{{repo}}}', dep=TRUE)" \ 19 | 20 | # render the manuscript into a docx, you'll need to edit this if you've 21 | # customised the location and name of your main Rmd file 22 | && R -e "rmarkdown::render('/{{{repo}}}/{{{rmd_path}}}')" 23 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(add_dependencies_to_description) 4 | export(as.package) 5 | export(create_compendium) 6 | export(github_pat) 7 | export(is.package) 8 | export(package_file) 9 | export(parse_deps) 10 | export(use_analysis) 11 | export(use_build_ignore) 12 | export(use_circleci) 13 | export(use_compendium) 14 | export(use_dockerfile) 15 | export(use_git) 16 | export(use_git_hook) 17 | export(use_git_quietly) 18 | export(use_github) 19 | export(use_github_links) 20 | export(use_readme_rmd) 21 | export(use_travis) 22 | import(utils) 23 | importFrom(curl,has_internet) 24 | importFrom(rmarkdown,render) 25 | importFrom(rstudioapi,isAvailable) 26 | importFrom(usethis,create_package) 27 | importFrom(usethis,use_git) 28 | importFrom(usethis,use_mit_license) 29 | importFrom(utils,browseURL) 30 | -------------------------------------------------------------------------------- /inst/templates/travis.yml-no-docker: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | 7 | # set pkg repo for the versioned CRAN hosted by Microsoft 8 | repos: 9 | MRAN: "https://mran.microsoft.com/snapshot/{{{date}}}" 10 | 11 | # install linux libraries that some R pkgs depend on, add more as needed 12 | addons: 13 | apt: 14 | packages: 15 | - libudunits2-dev 16 | 17 | script: 18 | # build and install custom library with custom functions 19 | - Rscript -e "devtools::install()" 20 | # render the main mansucript document into HTML/Word/PDF as specified in the Rmd 21 | # you may need to edit the path and file name to point to the Rmd file to render 22 | - R -e "rmarkdown::render('{{{rmd_path}}}')" 23 | 24 | # be more tolerant :) 25 | warnings_are_errors: false 26 | -------------------------------------------------------------------------------- /man/use_git_hook.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/infrastructure-git.R 3 | \name{use_git_hook} 4 | \alias{use_git_hook} 5 | \title{Add a git hook.} 6 | \usage{ 7 | use_git_hook(hook, script, pkg = ".") 8 | } 9 | \arguments{ 10 | \item{hook}{Hook name. One of "pre-commit", "prepare-commit-msg", 11 | "commit-msg", "post-commit", "applypatch-msg", "pre-applypatch", 12 | "post-applypatch", "pre-rebase", "post-rewrite", "post-checkout", 13 | "post-merge", "pre-push", "pre-auto-gc".} 14 | 15 | \item{script}{Text of script to run} 16 | 17 | \item{pkg}{Path to package. See \code{\link{as.package}} for more 18 | information.} 19 | } 20 | \description{ 21 | Add a git hook. 22 | } 23 | \seealso{ 24 | Other git infrastructure: \code{\link{use_github_links}}, 25 | \code{\link{use_github}}, \code{\link{use_git}} 26 | } 27 | \concept{git infrastructure} 28 | \keyword{internal} 29 | -------------------------------------------------------------------------------- /inst/templates/journal-of-archaeological-science.csl: -------------------------------------------------------------------------------- 1 | 2 | 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Build our Docker container and R pkg on Travis 2 | language: r 3 | sudo: required 4 | cache: packages 5 | 6 | env: 7 | global: 8 | - REPO=$DOCKER_USER/rrtools 9 | 10 | warnings_are_errors: false 11 | 12 | services: 13 | - docker 14 | 15 | after_success: 16 | # create & run container using our dockerfile, i.e. compile pkg and render Rmd to Word doc 17 | - docker build -t $REPO . 18 | # push our custom docker container to docker hub, env vars stored on travis-ci.org 19 | - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS 20 | - export REPO=$DOCKER_USER/rrtools 21 | - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo $TRAVIS_BRANCH ; fi` 22 | - docker build -f Dockerfile -t $REPO:$COMMIT . 23 | - docker tag $REPO:$COMMIT $REPO:$TAG 24 | - docker tag $REPO:$COMMIT $REPO:travis-$TRAVIS_BUILD_NUMBER 25 | - docker push $REPO 26 | -------------------------------------------------------------------------------- /analysis/templates/journal-of-archaeological-science.csl: -------------------------------------------------------------------------------- 1 | 2 | 15 | -------------------------------------------------------------------------------- /inst/templates/travis.yml-with-docker: -------------------------------------------------------------------------------- 1 | # Build our Docker container and R pkg on Travis 2 | 3 | env: 4 | global: 5 | - REPO=$DOCKER_USER/{{{repo}}} 6 | 7 | sudo: required 8 | 9 | warnings_are_errors: false 10 | 11 | language: generic 12 | 13 | services: 14 | - docker 15 | 16 | before_install: 17 | # create & run container using our dockerfile, i.e. compile pkg and render Rmd to Word doc 18 | - docker build -t $REPO . 19 | 20 | # push our custom docker container to docker hub, env vars stored on travis-ci.org 21 | after_success: 22 | - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS 23 | - export REPO=$DOCKER_USER/{{{repo}}} 24 | - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo $TRAVIS_BRANCH ; fi` 25 | - docker build -f Dockerfile -t $REPO:$COMMIT . 26 | - docker tag $REPO:$COMMIT $REPO:$TAG 27 | - docker tag $REPO:$COMMIT $REPO:travis-$TRAVIS_BUILD_NUMBER 28 | - docker push $REPO 29 | -------------------------------------------------------------------------------- /man/add_dependencies_to_description.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/manage_dependencies.R 3 | \name{add_dependencies_to_description} 4 | \alias{add_dependencies_to_description} 5 | \title{Searches for external packages and adds them to the Imports field in the description} 6 | \usage{ 7 | add_dependencies_to_description(path = getwd(), 8 | description_file = "DESCRIPTION", just_packages = FALSE) 9 | } 10 | \arguments{ 11 | \item{path}{location of individual file or directory where to search for scripts.} 12 | 13 | \item{description_file}{location of description file to be updated.} 14 | 15 | \item{just_packages}{just give back a character vector of the found packages.} 16 | } 17 | \description{ 18 | Scans script files (.R, .Rmd, .Rnw, .Rpres, etc.) for external package dependencies indicated by 19 | \code{library()}, \code{require()} or \code{::} and adds those packages to the Imports field in 20 | the package DESCRIPTION. 21 | } 22 | -------------------------------------------------------------------------------- /man/use_dockerfile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hello.R 3 | \name{use_dockerfile} 4 | \alias{use_dockerfile} 5 | \title{Add a Dockerfile} 6 | \usage{ 7 | use_dockerfile(pkg = ".", rocker = "verse", 8 | rmd_to_knit = "path_to_rmd") 9 | } 10 | \arguments{ 11 | \item{pkg}{defaults to the package in the current working directory} 12 | 13 | \item{rocker}{chr, the rocker image to base this container on} 14 | 15 | \item{rmd_to_knit, }{chr, path to the Rmd file to render in the Docker 16 | container, relative to the top level of the compendium 17 | (i.e. "analysis/paper/paper.Rmd"). There's no need to specify this if your Rmd 18 | to render is at "analysis/paper/paper.Rmd", "vignettes/paper/paper.Rmd" or 19 | "inst/paper/paper.Rmd". If you have a custom directory structure, and a custom 20 | file name for the Rmd file, you can specify that file path and name here so 21 | Docker can find the file to render in the container.B} 22 | } 23 | \description{ 24 | This will create a basic \file{Dockerfile} based on rocker/verse 25 | } 26 | -------------------------------------------------------------------------------- /man/create_compendium.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hello.R 3 | \name{create_compendium} 4 | \alias{create_compendium} 5 | \title{Quickly create a basic research compendium by combining several rrtools functions into one.} 6 | \usage{ 7 | create_compendium(pkgname, data_in_git = TRUE) 8 | } 9 | \arguments{ 10 | \item{pkgname}{location to create new package. The last component of the path will be used as the package name} 11 | 12 | \item{data_in_git}{should git track the files in the data directory? Default is TRUE} 13 | } 14 | \description{ 15 | In one step, this will create an R package, attach the MIT license to it, add the rrtools' README to it, initiate a Git repository and make an initial commit to track files in the package, and create the 'analysis' directory structure, and populate it with an R Markdown file and bib file. This function will not create a GitHub repository for the compendium, a Dockerfile, a Travis config file, or any package tests. Those require some interaction outside of R and are left to the user. 16 | } 17 | -------------------------------------------------------------------------------- /man/use_circleci.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hello.R 3 | \name{use_circleci} 4 | \alias{use_circleci} 5 | \title{Add a circleci config file} 6 | \usage{ 7 | use_circleci(pkg = ".", browse = interactive(), docker_hub = TRUE) 8 | } 9 | \arguments{ 10 | \item{pkg}{defaults to the package in the current working directory} 11 | 12 | \item{browse}{open a browser window to enable Circle-CI builds for the package automatically} 13 | 14 | \item{docker_hub}{should circleci push to Docker Hub after a successful build?} 15 | } 16 | \description{ 17 | This will build the Docker container on the Circle-CI service. 18 | The advantage of Circle-CI over Travis is that Circle-CI will freely work with 19 | private GitHub repositories. Only the paid service from Travis will work 20 | with private GitHub repositories. Before using this function you need 21 | to create an account with Circle-CI, using your GitHub account. If you want 22 | Circle-CI to run on a private GitHub repo, make sure you give Circle-CI 23 | access to 'all repos' when you log in with your GitHub credentials. 24 | } 25 | -------------------------------------------------------------------------------- /man/use_build_ignore.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/infrastructure.R 3 | \name{use_build_ignore} 4 | \alias{use_build_ignore} 5 | \alias{add_build_ignore} 6 | \title{Add a file to \code{.Rbuildignore}} 7 | \usage{ 8 | use_build_ignore(files, escape = TRUE, pkg = ".") 9 | } 10 | \arguments{ 11 | \item{files}{Name of file.} 12 | 13 | \item{escape}{If \code{TRUE}, the default, will escape \code{.} to 14 | \code{\\.} and surround with \code{^} and \code{$}.} 15 | 16 | \item{pkg}{package description, can be path or package name. See 17 | \code{\link{as.package}} for more information} 18 | } 19 | \value{ 20 | Nothing, called for its side effect. 21 | } 22 | \description{ 23 | \code{.Rbuildignore} has a regular expression on each line, but it's 24 | usually easier to work with specific file names. By default, will (crudely) 25 | turn a filename into a regular expression that will only match that 26 | path. Repeated entries will be silently removed. 27 | } 28 | \seealso{ 29 | Other infrastructure: \code{\link{use_readme_rmd}} 30 | } 31 | \concept{infrastructure} 32 | \keyword{internal} 33 | -------------------------------------------------------------------------------- /man/use_readme_rmd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hello.R 3 | \name{use_readme_rmd} 4 | \alias{use_readme_rmd} 5 | \title{Creates skeleton README files} 6 | \usage{ 7 | use_readme_rmd(pkg = ".", render_readme = TRUE) 8 | } 9 | \arguments{ 10 | \item{pkg}{package description, can be path or package name. See 11 | \code{\link{as.package}} for more information} 12 | 13 | \item{render_readme}{should the README.Rmd be directly rendered to 14 | a github markdown document? default: TRUE} 15 | } 16 | \description{ 17 | \code{README.Rmd} will be automatically 18 | added to \code{.Rbuildignore}. The resulting README is populated with default 19 | YAML frontmatter and R fenced code chunks (\code{Rmd}). 20 | Your readme should contain: 21 | \itemize{ 22 | \item a high-level description of the package and its goals 23 | \item R code to install from GitHub, if GitHub usage detected 24 | \item a basic example 25 | } 26 | } 27 | \examples{ 28 | \dontrun{ 29 | use_readme_rmd() 30 | } 31 | } 32 | \seealso{ 33 | Other infrastructure: \code{\link{use_build_ignore}} 34 | } 35 | \concept{infrastructure} 36 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2017 Ben Marwick 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /man/use_compendium.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hello.R 3 | \name{use_compendium} 4 | \alias{use_compendium} 5 | \title{Creates an R package suitable to use as a research compendium, and 6 | switches to the working directory of this new package, ready to work} 7 | \usage{ 8 | use_compendium(path, fields = getOption("usethis.description"), 9 | rstudio = rstudioapi::isAvailable(), open = interactive(), 10 | quiet = FALSE) 11 | } 12 | \arguments{ 13 | \item{path}{location to create new package. The last component of the path will be used as the package name} 14 | 15 | \item{fields}{list of description values to override default values or add additional values} 16 | 17 | \item{rstudio}{create an RStudio project file? (with \code{usethis::use_rstudio})} 18 | 19 | \item{open}{if TRUE and in RStudio, the new project is opened in a new instance. If TRUE and not in RStudio, the working directory is set to the new project} 20 | 21 | \item{quiet}{if FALSE, the default, prints informative messages} 22 | } 23 | \description{ 24 | This is usethis::create_package() with some additional messages to simplify the transition into the new project setting 25 | } 26 | -------------------------------------------------------------------------------- /man/use_github_links.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/infrastructure-git.R 3 | \name{use_github_links} 4 | \alias{use_github_links} 5 | \title{Add GitHub links to DESCRIPTION.} 6 | \usage{ 7 | use_github_links(pkg = ".", auth_token = github_pat(), 8 | host = "https://api.github.com") 9 | } 10 | \arguments{ 11 | \item{pkg}{Path to package. See \code{\link{as.package}} for more 12 | information.} 13 | 14 | \item{auth_token}{Provide a personal access token (PAT) from 15 | \url{https://github.com/settings/tokens}. Defaults to the \code{GITHUB_PAT} 16 | environment variable.} 17 | 18 | \item{host}{GitHub API host to use. Override with the endpoint-root for your 19 | GitHub enterprise instance, for example, 20 | "https://github.hostname.com/api/v3".} 21 | } 22 | \description{ 23 | Populates the URL and BugReports fields of DESCRIPTION with 24 | \code{https://github.com//} AND 25 | \code{https://github.com///issues}, respectively, unless 26 | those fields already exist. 27 | } 28 | \seealso{ 29 | Other git infrastructure: \code{\link{use_git_hook}}, 30 | \code{\link{use_github}}, \code{\link{use_git}} 31 | } 32 | \concept{git infrastructure} 33 | \keyword{internal} 34 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/99-references.Rmd: -------------------------------------------------------------------------------- 1 | 4 | 5 | \backmatter 6 | 7 | 11 | 12 | # References {-} 13 | 16 | \markboth{References}{References} 17 | 20 | \noindent 21 | 22 | 25 | 26 | \setlength{\parindent}{-0.20in} 27 | \setlength{\leftskip}{0.20in} 28 | \setlength{\parskip}{8pt} 29 | 30 | 31 | 34 | 35 | --- 36 | nocite: | 37 | @angel2000, @angel2001, @angel2002a 38 | ... 39 | 40 | 41 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | 2 | .onAttach <- function(...){ 3 | 4 | # check to see if git is installed using 'which git' 5 | which_git <- 6 | switch(Sys.info()[['sysname']], 7 | Windows= {system("where git", intern = TRUE)}, 8 | Linux = {system("which git", intern = TRUE)}, 9 | Darwin = {system("which git", intern = TRUE)}) 10 | 11 | if(!grepl("git", which_git[1])) { packageStartupMessage(red_cross(), " Git is not installed on this computer. Go to ", crayon::bgBlue("https://git-scm.com/downloads"), " to download Git for your computer. For more information on installing and using Git, see ", crayon::bgBlue("http://happygitwithr.com/")) 12 | 13 | } else { 14 | 15 | # check to see if git is configured with the user's name and email 16 | git_config <- git2r::config() 17 | git_user_name <- git_config$global$user.name 18 | git_user_email <- git_config$global$user.email 19 | 20 | if(!is.null(git_user_name)){ 21 | packageStartupMessage(green_tick(), " Git is installed on this computer, your username is ", 22 | usethis:::field(git_user_name)) 23 | } else { 24 | packageStartupMessage(red_cross(), " Git is installed on this computer, but not configured for use. For more information on configuring and using Git, see ", crayon::bgBlue("http://happygitwithr.com/")) 25 | } 26 | } 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /analysis/paper/references.bib: -------------------------------------------------------------------------------- 1 | @Article{Marwick2017, 2 | author="Marwick, Ben", 3 | title="Computational Reproducibility in Archaeological Research: Basic Principles and a Case Study of Their Implementation", 4 | journal="Journal of Archaeological Method and Theory", 5 | year="2017", 6 | month="Jun", 7 | day="01", 8 | volume="24", 9 | number="2", 10 | pages="424--450", 11 | abstract="The use of computers and complex software is pervasive in archaeology, yet their role in the analytical pipeline is rarely exposed for other researchers to inspect or reuse. This limits the progress of archaeology because researchers cannot easily reproduce each other's work to verify or extend it. Four general principles of reproducible research that have emerged in other fields are presented. An archaeological case study is described that shows how each principle can be implemented using freely available software. The costs and benefits of implementing reproducible research are assessed. The primary benefit, of sharing data in particular, is increased impact via an increased number of citations. The primary cost is the additional time required to enhance reproducibility, although the exact amount is difficult to quantify.", 12 | issn="1573-7764", 13 | doi="10.1007/s10816-015-9272-9", 14 | url="https://doi.org/10.1007/s10816-015-9272-9" 15 | } 16 | -------------------------------------------------------------------------------- /inst/templates/references.bib: -------------------------------------------------------------------------------- 1 | @Article{Marwick2017, 2 | author="Marwick, Ben", 3 | title="Computational Reproducibility in Archaeological Research: Basic Principles and a Case Study of Their Implementation", 4 | journal="Journal of Archaeological Method and Theory", 5 | year="2017", 6 | month="Jun", 7 | day="01", 8 | volume="24", 9 | number="2", 10 | pages="424--450", 11 | abstract="The use of computers and complex software is pervasive in archaeology, yet their role in the analytical pipeline is rarely exposed for other researchers to inspect or reuse. This limits the progress of archaeology because researchers cannot easily reproduce each other's work to verify or extend it. Four general principles of reproducible research that have emerged in other fields are presented. An archaeological case study is described that shows how each principle can be implemented using freely available software. The costs and benefits of implementing reproducible research are assessed. The primary benefit, of sharing data in particular, is increased impact via an increased number of citations. The primary cost is the additional time required to enhance reproducibility, although the exact amount is difficult to quantify.", 12 | issn="1573-7764", 13 | doi="10.1007/s10816-015-9272-9", 14 | url="https://doi.org/10.1007/s10816-015-9272-9" 15 | } 16 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: rrtools 2 | Type: Package 3 | Title: Creates a Reproducible Research Compendium 4 | Version: 0.1.0 5 | Authors@R: c(person("Ben", "Marwick", role = c("aut", "cre"), email = "benmarwick@gmail.com"), 6 | person("Daniel", "Knitter", role = "ctb"), 7 | person("Patrick", "Kennedy", role = "ctb"), 8 | person("Nils", "Muller-Scheessel", role = "ctb"), 9 | person("Martin", "Hinz", role = "ctb"), 10 | person("Clemens", "Schmid", role = "ctb"), 11 | person("Ricarda", "Braun", role = "ctb"), 12 | person("Wojciech", "Francuzik", role = "ctb"), 13 | person("Charles", "Gray", role = "ctb")) 14 | Maintainer: Ben Marwick 15 | Description: Instructions, templates, and functions for making a basic 16 | compendium suitable for doing reproducible research with R. 17 | License: MIT + file LICENSE 18 | Imports: devtools, git2r, whisker, rstudioapi, rmarkdown, knitr, here, 19 | bookdown, curl, RCurl, jsonlite, methods, httr, usethis, clisymbols, 20 | crayon, glue, readr (>= 1.1.1) 21 | Encoding: UTF-8 22 | LazyData: true 23 | URL: https://github.com/benmarwick/rrtools 24 | BugReports: https://github.com/benmarwick/rrtools/issues 25 | Suggests: testthat 26 | RoxygenNote: 6.1.1 27 | VignetteBuilder: knitr 28 | Date: 2019-01-15 29 | 30 | -------------------------------------------------------------------------------- /man/use_analysis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hello.R 3 | \name{use_analysis} 4 | \alias{use_analysis} 5 | \alias{add_analysis} 6 | \title{Adds an analysis directory (and sub-directories), and an Rmd file ready to write} 7 | \usage{ 8 | use_analysis(pkg = ".", location = "top_level", 9 | template = "paper.Rmd", data = list(), data_in_git = TRUE) 10 | } 11 | \arguments{ 12 | \item{pkg}{defaults to the package in the current working directory} 13 | 14 | \item{location}{the location where the directories and files will be written to. Defaults to a top-level 'analysis' directory. Other options are 'inst' (for the inst/ directory, so that all the contents will be included in the installed package) and 'vignettes' (as in a regular package vignette, all contents will be included in the installed package).} 15 | 16 | \item{template}{the template file to use to create the main analysis document. Defaults to 'paper.Rmd', ready to write R Markdown and knit to MS Word using bookdown} 17 | 18 | \item{data}{forwarded to \code{whisker::whisker.render}} 19 | 20 | \item{data_in_git}{should git track the files in the data directory?} 21 | } 22 | \description{ 23 | This will create \file{paper.Rmd}, \file{references.bib} 24 | and several others, and add \pkg{bookdown} to the imported packages listed in the DESCRIPTION file. 25 | } 26 | -------------------------------------------------------------------------------- /analysis/templates/template.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "My title" 3 | author: 4 | - author 1 5 | - other author 6 | date: '`r Sys.Date()`' 7 | output: word_document 8 | abstract: "My abstract \n" 9 | --- 10 | 11 | ```{r setup, include=FALSE} 12 | knitr::opts_chunk$set(echo = FALSE) 13 | ``` 14 | 15 | # Heading 1 16 | 17 | ## Heading 2 18 | 19 | ### Heading 3 20 | 21 | #### Heading 4 22 | 23 | ##### Heading 5 - this is for the page break with MS Word 24 | 25 | In the MS Word document, the following modifications must be made in the 'Modify Style' menu: 26 | 27 | + Set the font color to ‘white’ (rather than ‘Automatic’). 28 | + Select the smallest font size (8 rather than 11). 29 | + Select ‘Page break before’ in the ‘Line and Page Breaks’ tab. 30 | + Set the line spacing to ‘Exactly’ and ‘1 pt’ in the ‘Indents and Spacing’ tab. 31 | 32 | After these tweaks, the ‘Heading 5’ style will no longer format a heading of level 5. Instead it will insert a very small and white (and, thus, invisible) line followed by a page break. 33 | 34 | Now knit this doc, and edit the styles in the resulting docx file. Then rename as 'template' and use this in the yml: 35 | 36 | ``` 37 | output: 38 | word_document: 39 | reference_docx: templates/template.docx 40 | ``` 41 | 42 | Don't forget line numbers for JAS! Headings are bold, underline, nothing. And Arial Narrow 10pt for tables. 43 | 44 | See here for more information: http://rmarkdown.rstudio.com/articles_docx.html 45 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /inst/templates/word_templates/template.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "My title" 3 | author: 4 | - author 1 5 | - other author 6 | date: '`r Sys.Date()`' 7 | output: word_document 8 | abstract: "My abstract \n" 9 | --- 10 | 11 | ```{r setup, include=FALSE} 12 | knitr::opts_chunk$set(echo = FALSE) 13 | ``` 14 | 15 | # Heading 1 16 | 17 | ## Heading 2 18 | 19 | ### Heading 3 20 | 21 | #### Heading 4 22 | 23 | ##### Heading 5 - this is for the page break with MS Word 24 | 25 | In the MS Word document, the following modifications must be made in the 'Modify Style' menu: 26 | 27 | + Set the font color to ‘white’ (rather than ‘Automatic’). 28 | + Select the smallest font size (8 rather than 11). 29 | + Select ‘Page break before’ in the ‘Line and Page Breaks’ tab. 30 | + Set the line spacing to ‘Exactly’ and ‘1 pt’ in the ‘Indents and Spacing’ tab. 31 | 32 | After these tweaks, the ‘Heading 5’ style will no longer format a heading of level 5. Instead it will insert a very small and white (and, thus, invisible) line followed by a page break. 33 | 34 | Now knit this doc, and edit the styles in the resulting docx file. Then rename as 'template' and use this in the yml: 35 | 36 | ``` 37 | output: 38 | word_document: 39 | reference_docx: templates/template.docx 40 | ``` 41 | 42 | Don't forget line numbers for JAS! Headings are bold, underline, nothing. And Arial Narrow 10pt for tables. 43 | 44 | See here for more information: http://rmarkdown.rstudio.com/articles_docx.html 45 | -------------------------------------------------------------------------------- /inst/templates/CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /man/use_travis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hello.R 3 | \name{use_travis} 4 | \alias{use_travis} 5 | \alias{add_travis} 6 | \title{Add a travis config file} 7 | \usage{ 8 | use_travis(pkg = ".", browse = interactive(), docker = TRUE, 9 | rmd_to_knit = "path_to_rmd", ask = TRUE) 10 | } 11 | \arguments{ 12 | \item{pkg}{defaults to the package in the current working directory} 13 | 14 | \item{browse}{open a browser window to enable Travis builds for the package automatically} 15 | 16 | \item{docker}{logical, if TRUE (the default) the travis config will build a Docker container according to the instructions in the Dockerfile, and build and install the package in that container. If FALSE, the standard config for R on travis is used.} 17 | 18 | \item{rmd_to_knit}{path to .Rmd file that should be knitted by the virtual build environment: default is "path_to_rmd" which causes the function to search for a paper.Rmd file by itself.} 19 | 20 | \item{ask}{should the function ask with \code{yesno()} if an old .travis.yml should be overwritten with a new one? default: TRUE} 21 | } 22 | \description{ 23 | This has two options. One is the same as `usethis::use_travis`, a vanilla travis config that builds, installs and runs the custom package on travis. The other type of configuration directs travis to build the Docker container (according to the instructions in your Dockerfile) and push the successful result to Docker Hub. Using a Dockerfile is recommended because it gives greater isolation of the computational enviroment, and will result in much faster build times on travis. 24 | } 25 | -------------------------------------------------------------------------------- /tests/testthat/test_use_travis.R: -------------------------------------------------------------------------------- 1 | context("use_travis()") 2 | 3 | # Idea for the future: The validity of travis.yml files can be checked automatically: 4 | # https://docs.travis-ci.com/user/travis-lint 5 | 6 | #### run function without docker = TRUE #### 7 | 8 | suppressMessages( 9 | rrtools::use_travis( 10 | package_path, 11 | browse = FALSE, 12 | docker = FALSE, 13 | ask = FALSE 14 | ) 15 | ) 16 | 17 | #### check results without docker = TRUE #### 18 | 19 | test_that("use_travis() generates .travis.yml", { 20 | expect_true( 21 | ".travis.yml" %in% list.files(package_path, all.files = TRUE) 22 | ) 23 | }) 24 | 25 | test_that(".travis.yml is a text file, has some text and an essential line", { 26 | travis <- readLines(file.path(package_path, ".travis.yml")) 27 | expect_gt( 28 | length(travis), 29 | 1 30 | ) 31 | expect_true( 32 | "language: R" %in% travis 33 | ) 34 | }) 35 | 36 | #### cleanup after test without docker #### 37 | 38 | file.remove( 39 | file.path(package_path, ".travis.yml") 40 | ) 41 | 42 | #### run function with docker = TRUE #### 43 | 44 | suppressMessages( 45 | rrtools::use_travis( 46 | package_path, 47 | browse = FALSE, 48 | docker = TRUE, 49 | ask = FALSE 50 | ) 51 | ) 52 | 53 | #### check results with docker = TRUE #### 54 | 55 | test_that("use_travis() generates .travis.yml", { 56 | expect_true( 57 | ".travis.yml" %in% list.files(package_path, all.files = TRUE) 58 | ) 59 | }) 60 | 61 | test_that(".travis.yml is a text file, has some text and an essential line", { 62 | travis <- readLines(file.path(package_path, ".travis.yml")) 63 | expect_gt( 64 | length(travis), 65 | 1 66 | ) 67 | expect_true( 68 | "language: generic" %in% travis 69 | ) 70 | }) 71 | -------------------------------------------------------------------------------- /tests/testthat/test_add_dependencies_to_description.R: -------------------------------------------------------------------------------- 1 | context("add_dependencies_to_description()") 2 | 3 | #### preparations #### 4 | 5 | # create artificial files with some dependencies 6 | testfile_1 <- file.path(package_path, "/R/testfile_1.R") 7 | writeLines( 8 | c("library(knitr)", "require(glue)", "rmarkdown::draft()"), 9 | con = testfile_1 10 | ) 11 | 12 | if (!dir.exists(file.path(package_path, "/playground"))) { 13 | dir.create(file.path(package_path, "/playground")) 14 | } 15 | testfile_2 <- file.path(package_path, "/playground/testfile_2.R") 16 | writeLines( 17 | c("library(bookdown)", "require(git2r)", "usethis::use_template()"), 18 | con = testfile_2 19 | ) 20 | 21 | description_path <- paste0(package_path, "/DESCRIPTION") 22 | description_unchanged <- readLines(description_path) 23 | 24 | #### run function to change description #### 25 | 26 | rrtools::add_dependencies_to_description( 27 | package_path, 28 | description_path, 29 | just_packages = FALSE 30 | ) 31 | 32 | #### check results #### 33 | 34 | description_changed <- readLines(description_path) 35 | 36 | test_that("the DESCRIPTION file has changed exactly as expected", { 37 | expect_equal( 38 | all.equal( 39 | description_unchanged, description_changed 40 | ), 41 | "Lengths (13, 20) differ (string compare on first 13)" 42 | ) 43 | }) 44 | 45 | test_that("the DESCRIPTION file now actually contains the package dependencies", { 46 | expect_equal( 47 | grep("bookdown | git2r | glue | knitr | rmarkdown | usethis", description_changed), 48 | c(15:20) 49 | ) 50 | }) 51 | 52 | #### check functions ability to provide packages vector #### 53 | 54 | test_that("add_dependencies_to_description provides correct packages vector if just_packages = TRUE", { 55 | expect_equal( 56 | rrtools::add_dependencies_to_description( 57 | package_path, 58 | description_path, 59 | just_packages = TRUE 60 | ), 61 | c("bookdown", "git2r", "glue", "knitr", "rmarkdown", "usethis") 62 | ) 63 | }) 64 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/98-colophon.Rmd: -------------------------------------------------------------------------------- 1 | # Colophon {-} 2 | 3 | This document is set in [EB Garamond](https://github.com/georgd/EB-Garamond), [Source Code Pro](https://github.com/adobe-fonts/source-code-pro/) and [Lato](http://www.latofonts.com/lato-free-fonts/). The body text is set at 11pt with $\familydefault$. 4 | 5 | It was written in R Markdown and $\LaTeX$, and rendered into PDF using [huskydown](https://github.com/benmarwick/huskydown) and [bookdown](https://github.com/rstudio/bookdown). 6 | 7 | This document was typeset using the XeTeX typesetting system, and the [University of Washington Thesis class](http://staff.washington.edu/fox/tex/) class created by Jim Fox. Under the hood, the [University of Washington Thesis LaTeX template](https://github.com/UWIT-IAM/UWThesis) is used to ensure that documents conform precisely to submission standards. Other elements of the document formatting source code have been taken from the [Latex, Knitr, and RMarkdown templates for UC Berkeley's graduate thesis](https://github.com/stevenpollack/ucbthesis), and [Dissertate: a LaTeX dissertation template to support the production and typesetting of a PhD dissertation at Harvard, Princeton, and NYU](https://github.com/suchow/Dissertate) 8 | 9 | The source files for this thesis, along with all the data files, have been organised into an R package, xxx, which is available at https://github.com/xxx/xxx. A hard copy of the thesis can be found in the University of Washington library. 10 | 11 | This version of the thesis was generated on `r Sys.time()`. The repository is currently at this commit: 12 | 13 | ```{r echo = FALSE, eval = FALSE} 14 | # I've set eval=FALSE to ensure Travis-CI can run 15 | # if you're not using Travis-CI, then eval=TRUE will be fine 16 | library(git2r) 17 | if ( in_repository() ) { 18 | summary(commits()[[1]]) 19 | } else { 20 | message("We are not in a git repository") 21 | } 22 | ``` 23 | 24 | The computational environment that was used to generate this version is as follows: 25 | 26 | ```{r echo = FALSE} 27 | devtools::session_info() 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /inst/templates/omni-README: -------------------------------------------------------------------------------- 1 | {{#Rmd}} 2 | --- 3 | output: github_document 4 | --- 5 | 6 | 7 | 8 | ```{r, echo = FALSE} 9 | knitr::opts_chunk$set( 10 | collapse = TRUE, 11 | comment = "#>", 12 | fig.path = "README-" 13 | ) 14 | # Please put your title here to include it in the file below. 15 | Title <- "Title of your paper goes here" 16 | ``` 17 | 18 | {{/Rmd}} 19 | 20 | # {{{ package }}} 21 | 22 | This repository contains the data and code for our paper: 23 | 24 | > Authors, (YYYY). _`r Title`_. Name of journal/book 25 | 26 | Our pre-print is online here: 27 | 28 | > Authors, (YYYY). _`r Title`_. Name of journal/book, Accessed `r format(Sys.Date(), "%d %b %Y")`. Online at 29 | 30 | 31 | ### How to cite 32 | 33 | Please cite this compendium as: 34 | 35 | > Authors, (`r format(Sys.Date(), "%Y")`). _Compendium of R code and data for `r Title`_. Accessed `r format(Sys.Date(), "%d %b %Y")`. Online at 36 | 37 | ### How to download or install 38 | 39 | You can download the compendium as a zip from from this URL: <{{{url}}}/archive/master.zip> 40 | 41 | Or you can install this compendium as an R package, {{{ package }}}, from GitHub with: 42 | {{#github}} 43 | ```{r gh-installation, eval = FALSE} 44 | # install.packages("devtools") 45 | devtools::install_github("{{{username}}}/{{{repo}}}") 46 | ``` 47 | {{/github}} 48 | 49 | ### Licenses 50 | 51 | **Text and figures :** [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/) 52 | 53 | **Code :** See the [DESCRIPTION](DESCRIPTION) file 54 | 55 | **Data :** [CC-0](http://creativecommons.org/publicdomain/zero/1.0/) attribution requested in reuse 56 | 57 | ### Contributions 58 | 59 | We welcome contributions from everyone. Before you get started, please see our [contributor guidelines](CONTRIBUTING.md). Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. 60 | 61 | -------------------------------------------------------------------------------- /inst/templates/paper.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Title Goes Here" 3 | author: 4 | - Author One 5 | - Author Two 6 | date: "`r format(Sys.time(), '%d %B, %Y')`" 7 | output: 8 | bookdown::html_document2: 9 | fig_caption: yes 10 | reference_docx: "../templates/template.docx" # Insert path for the DOCX file 11 | bibliography: references.bib 12 | csl: "../templates/journal-of-archaeological-science.csl" # Insert path for the bib-style 13 | abstract: | 14 | Text of abstract 15 | keywords: | 16 | keyword 1; keyword 2; keyword 3 17 | highlights: | 18 | These are the highlights. 19 | --- 20 | 21 | 22 | 23 | 24 | ```{r, setup, echo = FALSE} 25 | knitr::opts_chunk$set( 26 | collapse = TRUE, 27 | warning = FALSE, 28 | message = FALSE, 29 | echo = FALSE, 30 | comment = "#>", 31 | fig.path = "../figures/" 32 | ) 33 | ``` 34 | 35 | # Introduction 36 | 37 | Here is a citation [@Marwick2017] 38 | 39 | # Background 40 | 41 | ```{r demo, eval = FALSE} 42 | 1 + 1 43 | ``` 44 | 45 | # Methods 46 | 47 | # Results 48 | 49 | ```{r get-data, eval = FALSE} 50 | # Note the path that we need to use to access our data files when rendering this document 51 | my_data <- readr::read_csv(here::here('analysis', 'data', 'raw_data', 'my_csv_file.csv')) 52 | ``` 53 | 54 | # Discussion 55 | 56 | # Conclusion 57 | 58 | # Acknowledgements 59 | 60 | 61 | ##### pagebreak 62 | 63 | # References 64 | 65 |
66 | 67 | ##### pagebreak 68 | 69 | ### Colophon 70 | 71 | This report was generated on `r Sys.time()` using the following computational environment and dependencies: 72 | 73 | ```{r colophon, cache = FALSE} 74 | # which R packages and versions? 75 | devtools::session_info() 76 | ``` 77 | 78 | The current Git commit details are: 79 | 80 | ```{r} 81 | # what commit is this file at? 82 | git2r::repository(here::here()) 83 | ``` 84 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We love pull requests from everyone. By participating in this project, you 4 | agree to abide by our [code of conduct](CONDUCT.md). 5 | 6 | ## Getting Started 7 | 8 | * Make sure you have a [GitHub account](https://github.com/signup/free). If you are not familar with git and GitHub, take a look at to get started. 9 | * [Submit a post for your issue](https://github.com/benmarwick/rrtools/issues/), assuming one does not already exist. 10 | * Clearly describe your issue, including steps to reproduce when it is a bug, or some justification for a proposed improvement. 11 | * [Fork](https://github.com/benmarwick/rrtools/#fork-destination-box) the repository on GitHub to make a copy of the repository on your account. Or use this line in your shell terminal: 12 | 13 | `git clone git@github.com:your-username/rrtools.git` 14 | 15 | ## Making changes 16 | 17 | * Edit the files, save often, and make commits of logical units, where each commit indicates one concept 18 | * Follow our [style guide](http://adv-r.had.co.nz/Style.html). 19 | * Make sure you write [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 20 | * Make sure you have added the necessary tests for your code changes. 21 | * Run _all_ the tests using `devtools::check()` to assure nothing else was accidentally broken. 22 | * If you need help or unsure about anything, post an update to [your issue](https://github.com/benmarwick/rrtools/issues/). 23 | 24 | ## Submitting your changes 25 | 26 | Push to your fork and [submit a pull request](https://github.com/benmarwick/rrtools/compare/). 27 | 28 | At this point you're waiting on us. We like to at least comment on pull requests 29 | within a few days (and, typically, one business day). We may suggest 30 | some changes or improvements or alternatives. 31 | 32 | Some things you can do that will increase the chance that your pull request is accepted: 33 | 34 | * Engage in discussion on [your issue](https://github.com/benmarwick/rrtools/issues/). 35 | * Be familiar with the background literature cited in the [README](README.Rmd) 36 | * Write tests that pass `devtools::check()`. 37 | * Follow our [code style guide](http://adv-r.had.co.nz/Style.html). 38 | * Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /inst/templates/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We love pull requests from everyone. By participating in this project, you 4 | agree to abide by our [code of conduct](CONDUCT.md). 5 | 6 | ## Getting Started 7 | 8 | * Make sure you have a [GitHub account](https://github.com/signup/free). If you are not familar with git and GitHub, take a look at to get started. 9 | * [Submit a post for your issue](https://github.com/{{{username}}}/{{{repo}}}/issues/), assuming one does not already exist. 10 | * Clearly describe your issue, including steps to reproduce when it is a bug, or some justification for a proposed improvement. 11 | * [Fork](https://github.com/{{{username}}}/{{{repo}}}/#fork-destination-box) the repository on GitHub to make a copy of the repository on your account. Or use this line in your shell terminal: 12 | 13 | `git clone git@github.com:your-username/{{{repo}}}.git` 14 | 15 | ## Making changes 16 | 17 | * Edit the files, save often, and make commits of logical units, where each commit indicates one concept 18 | * Follow our [style guide](http://adv-r.had.co.nz/Style.html). 19 | * Make sure you write [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 20 | * Make sure you have added the necessary tests for your code changes. 21 | * Run _all_ the tests using `devtools::check()` to assure nothing else was accidentally broken. 22 | * If you need help or unsure about anything, post an update to [your issue](https://github.com/{{{username}}}/{{{repo}}}/issues/). 23 | 24 | ## Submitting your changes 25 | 26 | Push to your fork and [submit a pull request](https://github.com/{{{username}}}/{{{repo}}}/compare/). 27 | 28 | At this point you're waiting on us. We like to at least comment on pull requests 29 | within a few days (and, typically, one business day). We may suggest 30 | some changes or improvements or alternatives. 31 | 32 | Some things you can do that will increase the chance that your pull request is accepted: 33 | 34 | * Engage in discussion on [your issue](https://github.com/{{{username}}}/{{{repo}}}/issues/). 35 | * Be familiar with the backround literature cited in the [README](README.Rmd) 36 | * Write tests that pass. 37 | * Follow our [code style guide](http://adv-r.had.co.nz/Style.html). 38 | * Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /analysis/paper/paper.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Title Goes Here" 3 | author: 4 | - Author One 5 | - Author Two 6 | date: "`r format(Sys.time(), '%d %B, %Y')`" 7 | output: 8 | bookdown::word_document2: 9 | fig_caption: yes 10 | reference_docx: "../templates/template.docx" # Insert path for the DOCX file 11 | bibliography: references.bib 12 | csl: "../templates/journal-of-archaeological-science.csl" # Insert path for the bib-style 13 | abstract: | 14 | Text of abstract 15 | keywords: | 16 | keyword 1; keyword 2; keyword 3 17 | highlights: | 18 | These are the highlights. 19 | --- 20 | 21 | 22 | 23 | ```{r, setup, echo = FALSE} 24 | knitr::opts_chunk$set( 25 | collapse = TRUE, 26 | warning = FALSE, 27 | message = FALSE, 28 | echo = FALSE, 29 | comment = "#>", 30 | fig.path = "../figures/" 31 | ) 32 | 33 | library(rrtools) # Or use devtools::load_all('.', quiet = T) if your code is in script files, rather than as functions in the `/R` directory 34 | ``` 35 | 36 | # Introduction 37 | 38 | Here is a citation [@Marwick2017] 39 | 40 | # Background 41 | 42 | ```{r demo, eval = FALSE} 43 | 1 + 1 44 | ``` 45 | 46 | # Methods 47 | 48 | # Results 49 | 50 | ```{r get-data, eval = FALSE} 51 | # Note the path that we need to use to access our data files when rendering this document 52 | my_data <- readr::read_csv("../data/raw_data/my_csv_file.csv") 53 | ``` 54 | 55 | # Discussion 56 | 57 | # Conclusion 58 | 59 | # Acknowledgements 60 | 61 | 62 | ##### pagebreak 63 | 64 | # References 65 | 66 |
67 | 68 | ##### pagebreak 69 | 70 | ### Colophon 71 | 72 | This report was generated on `r Sys.time()` using the following computational environment and dependencies: 73 | 74 | ```{r colophon, cache = FALSE} 75 | # which R packages and versions? 76 | devtools::session_info() 77 | ``` 78 | 79 | The current Git commit details are: 80 | 81 | ```{r} 82 | # what commit is this file at? You may need to change the path value 83 | # if your Rmd is not in analysis/paper/ 84 | git2r::repository("../..") 85 | ``` 86 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/chemarr.sty: -------------------------------------------------------------------------------- 1 | % File: chemarr.sty 2 | % Version: 2001/06/22 v1.1 3 | % Author: Heiko Oberdiek 4 | % Email: 5 | % 6 | % Copyright: Copyright (C) 2001 Heiko Oberdiek. 7 | % 8 | % This program may be distributed and/or modified under 9 | % the conditions of the LaTeX Project Public License, 10 | % either version 1.2 of this license or (at your option) 11 | % any later version. The latest version of this license 12 | % is in 13 | % http://www.latex-project.org/lppl.txt 14 | % and version 1.2 or later is part of all distributions 15 | % of LaTeX version 1999/12/01 or later. 16 | % 17 | % Function: Very often chemists need a longer version 18 | % of reaction arrows (\rightleftharpoons) with 19 | % the possibility to put text above and below. 20 | % Analogous to amsmath's \xrightarrow and 21 | % \xleftarrow this package provides the macro 22 | % \xrightleftharpoons. 23 | % 24 | % Requirement: amsmath 25 | % Use: LaTeX: \usepackage{chemarr} 26 | % \xrightleftharpoons[below]{above} 27 | % 28 | % History: 2001/06/21 v1.0: 29 | % * first public version 30 | % 2001/06/22 v1.1: 31 | % * documentation fixes 32 | % 33 | \NeedsTeXFormat{LaTeX2e} 34 | \ProvidesPackage{chemarr}% 35 | [2001/06/22 v1.1 Chemical reaction arrows (HO)] 36 | % 37 | \RequirePackage{amsmath} 38 | % The package amsmath is needed for the following commands: 39 | % \ext@arrow, \@ifnotempty, \arrowfill@ 40 | % \relbar, \std@minus 41 | % \@ifempty, \@xifempty, \@xp 42 | % 43 | % In fontmath.ltx \rightleftharpoons is defined with 44 | % a vertical space of 2pt. 45 | % 46 | \newcommand{\xrightleftharpoons}[2][]{% 47 | \ensuremath{% 48 | \mathrel{% 49 | \settoheight{\dimen@}{\raise 2pt\hbox{$\rightharpoonup$}}% 50 | \setlength{\dimen@}{-\dimen@}% 51 | \edef\CA@temp{\the\dimen@}% 52 | \settoheight\dimen@{$\rightleftharpoons$}% 53 | \addtolength{\dimen@}{\CA@temp}% 54 | \raisebox{\dimen@}{% 55 | \rlap{% 56 | \raisebox{2pt}{% 57 | $% 58 | \ext@arrow 0359\rightharpoonupfill@{\hphantom{#1}}{#2}% 59 | $% 60 | }% 61 | }% 62 | \hbox{% 63 | $% 64 | \ext@arrow 3095\leftharpoondownfill@{#1}{\hphantom{#2}}% 65 | $% 66 | }% 67 | }% 68 | }% 69 | }% 70 | } 71 | \newcommand*{\leftharpoondownfill@}{% 72 | \arrowfill@\leftharpoondown\relbar\relbar 73 | } 74 | \newcommand*{\rightharpoonupfill@}{% 75 | \arrowfill@\relbar\relbar\rightharpoonup 76 | } 77 | \endinput 78 | -------------------------------------------------------------------------------- /man/use_github.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/infrastructure-git.R 3 | \name{use_github} 4 | \alias{use_github} 5 | \title{Connect a local repo with GitHub.} 6 | \usage{ 7 | use_github(auth_token = github_pat(), private = FALSE, pkg = ".", 8 | host = "https://api.github.com", protocol = c("ssh", "https"), 9 | credentials = NULL) 10 | } 11 | \arguments{ 12 | \item{auth_token}{Provide a personal access token (PAT) from 13 | \url{https://github.com/settings/tokens}. Defaults to the \code{GITHUB_PAT} 14 | environment variable.} 15 | 16 | \item{private}{If \code{TRUE}, creates a private repository.} 17 | 18 | \item{pkg}{Path to package. See \code{\link{as.package}} for more 19 | information.} 20 | 21 | \item{host}{GitHub API host to use. Override with the endpoint-root for your 22 | GitHub enterprise instance, for example, 23 | "https://github.hostname.com/api/v3".} 24 | 25 | \item{protocol}{transfer protocol, either "ssh" (the default) or "https"} 26 | 27 | \item{credentials}{A \code{\link[git2r]{cred_ssh_key}} specifying specific 28 | ssh credentials or NULL for default ssh key and ssh-agent behaviour. 29 | Default is NULL.} 30 | } 31 | \description{ 32 | If the current repo does not use git, calls \code{\link{use_git}} 33 | automatically. \code{\link{use_github_links}} is called to populate the 34 | \code{URL} and \code{BugReports} fields of DESCRIPTION. 35 | } 36 | \section{Authentication}{ 37 | 38 | 39 | A new GitHub repo will be created via the GitHub API, therefore you must 40 | provide a GitHub personal access token (PAT) via the argument 41 | \code{auth_token}, which defaults to the value of the \code{GITHUB_PAT} 42 | environment variable. Obtain a PAT from 43 | \url{https://github.com/settings/tokens}. The "repo" scope is required 44 | which is one of the default scopes for a new PAT. 45 | 46 | The argument \code{protocol} reflects how you wish to authenticate with 47 | GitHub for this repo in the long run. For either \code{protocol}, a remote 48 | named "origin" is created, an initial push is made using the specified 49 | \code{protocol}, and a remote tracking branch is set. The URL of the 50 | "origin" remote has the form \code{git@github.com:/.git} 51 | (\code{protocol = "ssh"}, the default) or 52 | \code{https://github.com//.git} (\code{protocol = 53 | "https"}). For \code{protocol = "ssh"}, it is assumed that public and 54 | private keys are in the default locations, \code{~/.ssh/id_rsa.pub} and 55 | \code{~/.ssh/id_rsa}, respectively, and that \code{ssh-agent} is configured 56 | to manage any associated passphrase. Alternatively, specify a 57 | \code{\link[git2r]{cred_ssh_key}} object via the \code{credentials} 58 | parameter. 59 | } 60 | 61 | \examples{ 62 | \dontrun{ 63 | ## to use default ssh protocol 64 | create("testpkg") 65 | use_github(pkg = "testpkg") 66 | 67 | ## or use https 68 | create("testpkg2") 69 | use_github(pkg = "testpkg2", protocol = "https") 70 | } 71 | } 72 | \seealso{ 73 | Other git infrastructure: \code{\link{use_git_hook}}, 74 | \code{\link{use_github_links}}, \code{\link{use_git}} 75 | } 76 | \concept{git infrastructure} 77 | -------------------------------------------------------------------------------- /R/package-deps.R: -------------------------------------------------------------------------------- 1 | # unexported fns from devtools, we include them here so 2 | # we don't have to use ::: 3 | # from https://github.com/hadley/devtools/blob/26c507b128fdaa1911503348fedcf20d2dd30a1d/R/package-deps.r 4 | 5 | #' Parse package dependency strings. 6 | #' 7 | #' @param string to parse. Should look like \code{"R (>= 3.0), ggplot2"} etc. 8 | #' @return list of two character vectors: \code{name} package names, 9 | #' and \code{version} package versions. If version is not specified, 10 | #' it will be stored as NA. 11 | #' @keywords internal 12 | #' @export 13 | #' @examples 14 | #' parse_deps("httr (< 2.1),\nRCurl (>= 3)") 15 | #' # only package dependencies are returned 16 | #' parse_deps("utils (== 2.12.1),\ntools,\nR (>= 2.10),\nmemoise") 17 | parse_deps <- function(string) { 18 | if (is.null(string)) return() 19 | stopifnot(is.character(string), length(string) == 1) 20 | if (grepl("^\\s*$", string)) return() 21 | 22 | pieces <- strsplit(string, "[[:space:]]*,[[:space:]]*")[[1]] 23 | 24 | # Get the names 25 | names <- gsub("\\s*\\(.*?\\)", "", pieces) 26 | names <- gsub("^\\s+|\\s+$", "", names) 27 | 28 | # Get the versions and comparison operators 29 | versions_str <- pieces 30 | have_version <- grepl("\\(.*\\)", versions_str) 31 | versions_str[!have_version] <- NA 32 | 33 | compare <- sub(".*\\((\\S+)\\s+.*\\)", "\\1", versions_str) 34 | versions <- sub(".*\\(\\S+\\s+(.*)\\)", "\\1", versions_str) 35 | 36 | # Check that non-NA comparison operators are valid 37 | compare_nna <- compare[!is.na(compare)] 38 | compare_valid <- compare_nna %in% c(">", ">=", "==", "<=", "<") 39 | if(!all(compare_valid)) { 40 | stop("Invalid comparison operator in dependency: ", 41 | paste(compare_nna[!compare_valid], collapse = ", ")) 42 | } 43 | 44 | deps <- data.frame(name = names, compare = compare, 45 | version = versions, stringsAsFactors = FALSE) 46 | 47 | # Remove R dependency 48 | deps[names != "R", ] 49 | } 50 | 51 | 52 | #' Check that the version of an imported package satisfies the requirements 53 | #' 54 | #' @param dep_name The name of the package with objects to import 55 | #' @param dep_ver The version of the package 56 | #' @param dep_compare The comparison operator to use to check the version 57 | #' @keywords internal 58 | check_dep_version <- function(dep_name, dep_ver = NA, dep_compare = NA) { 59 | if (!requireNamespace(dep_name, quietly = TRUE)) { 60 | stop("Dependency package ", dep_name, " not available.") 61 | } 62 | 63 | if (xor(is.na(dep_ver), is.na(dep_compare))) { 64 | stop("dep_ver and dep_compare must be both NA or both non-NA") 65 | 66 | } else if(!is.na(dep_ver) && !is.na(dep_compare)) { 67 | 68 | compare <- match.fun(dep_compare) 69 | if (!compare( 70 | as.numeric_version(getNamespaceVersion(dep_name)), 71 | as.numeric_version(dep_ver))) { 72 | 73 | warning("Need ", dep_name, " ", dep_compare, 74 | " ", dep_ver, 75 | " but loaded version is ", getNamespaceVersion(dep_name)) 76 | } 77 | } 78 | return(TRUE) 79 | } 80 | -------------------------------------------------------------------------------- /R/infrastructure.R: -------------------------------------------------------------------------------- 1 | # unexported fns from devtools, we include them here so 2 | # we don't have to use ::: 3 | # from https://github.com/hadley/devtools/blob/ad6f28ef9de6a02e1ea300af45d34deccc40bd2f/R/infrastructure.R 4 | 5 | yesno <- function(...) { 6 | yeses <- c("Yes", "Definitely", "For sure", "Yup", "Yeah", "I agree", "Absolutely") 7 | nos <- c("No way", "Not yet", "I forget", "No", "Nope", "Uhhhh... Maybe?") 8 | 9 | cat(paste0(..., collapse = "")) 10 | qs <- c(sample(yeses, 1), sample(nos, 2)) 11 | rand <- sample(length(qs)) 12 | 13 | menu(qs[rand]) != which(rand == 1) 14 | } 15 | 16 | union_write <- function(path, new_lines) { 17 | if (file.exists(path)) { 18 | lines <- readLines(path, warn = FALSE) 19 | } else { 20 | lines <- character() 21 | } 22 | 23 | all <- union(lines, new_lines) 24 | writeLines(all, path) 25 | } 26 | 27 | 28 | add_desc_package <- function(pkg = ".", field, name) { 29 | pkg <- as.package(pkg) 30 | desc_path <- file.path(pkg$path, "DESCRIPTION") 31 | 32 | desc <- read_dcf(desc_path) 33 | old <- desc[[field]] 34 | if (is.null(old)) { 35 | new <- name 36 | changed <- TRUE 37 | } else { 38 | if (!grepl(paste0('\\b', name, '\\b'), old)) { 39 | new <- paste0(old, ",\n ", name) 40 | changed <- TRUE 41 | } else { 42 | changed <- FALSE 43 | } 44 | } 45 | if (changed) { 46 | desc[[field]] <- new 47 | write_dcf(desc_path, desc) 48 | } 49 | invisible(changed) 50 | } 51 | 52 | 53 | #' Add a file to \code{.Rbuildignore} 54 | #' 55 | #' \code{.Rbuildignore} has a regular expression on each line, but it's 56 | #' usually easier to work with specific file names. By default, will (crudely) 57 | #' turn a filename into a regular expression that will only match that 58 | #' path. Repeated entries will be silently removed. 59 | #' 60 | #' @param pkg package description, can be path or package name. See 61 | #' \code{\link{as.package}} for more information 62 | #' @param files Name of file. 63 | #' @param escape If \code{TRUE}, the default, will escape \code{.} to 64 | #' \code{\\.} and surround with \code{^} and \code{$}. 65 | #' @return Nothing, called for its side effect. 66 | #' @export 67 | #' @aliases add_build_ignore 68 | #' @family infrastructure 69 | #' @keywords internal 70 | use_build_ignore <- function(files, escape = TRUE, pkg = ".") { 71 | pkg <- as.package(pkg) 72 | 73 | if (escape) { 74 | files <- paste0("^", gsub("\\.", "\\\\.", files), "$") 75 | } 76 | 77 | path <- file.path(pkg$path, ".Rbuildignore") 78 | union_write(path, files) 79 | 80 | invisible(TRUE) 81 | } 82 | 83 | 84 | open_in_rstudio <- function(path) { 85 | if (!rstudioapi::isAvailable()) 86 | return() 87 | 88 | if (!rstudioapi::hasFun("navigateToFile")) 89 | return() 90 | 91 | rstudioapi::navigateToFile(path) 92 | 93 | } 94 | 95 | can_overwrite <- function(path, ask = TRUE) { 96 | name <- basename(path) 97 | 98 | if (!file.exists(path)) { 99 | TRUE 100 | } else if (ask && (interactive() && !yesno("Overwrite `", name, "`?"))) { 101 | TRUE 102 | } else { 103 | FALSE 104 | } 105 | } 106 | 107 | -------------------------------------------------------------------------------- /inst/notes/Workflow_summerschool.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Workflow" 3 | output: html_document 4 | --- 5 | 6 | ```{r setup, include=FALSE} 7 | knitr::opts_chunk$set(echo = TRUE) 8 | library(knitr) 9 | library(bookdown) 10 | library(rmarkdown) 11 | ``` 12 | 13 | 14 | This is a workflow to create the "reproduceability" we learned in the Summer School "Reproducable Research in Landscape Archaeology" by Ben Marwick et al. 17th-21st July 2017. 15 | 16 | 17 | # Setup 18 | 19 | Start Rstudio and start by creating your package: 20 | 21 | ```{r , eval=FALSE} 22 | devtools::create("packagename") 23 | ``` 24 | This creates also the description, namespace and manuals-folder (man). 25 | Remember to edit the description. Especially the imports should be continously updated! 26 | 27 | Levae the other two alone... 28 | 29 | ```{r, eval = FALSE} 30 | devtools::use_mit_license() 31 | ``` 32 | This puts the MIT licence in the DESCRIPTION and creates the license-document, which you need to edit to give your name. Think about your decision, do you want to use the MIT-license or another one? 33 | 34 | ## Github 35 | 36 | ```{r, eval=FALSE} 37 | devtools::use_github() 38 | ``` 39 | This creates your local github repository for the package. Go online to github.com/yourname to create your online repository with the same name. Commit and push your package. 40 | 41 | ```{r, eval=FALSE} 42 | devtools::use_readme_rmd() 43 | devtools::use_travis() 44 | ``` 45 | With these you create the README.Rmd and the travis.yml. 46 | 47 | The README.Rmd needs to be updated with your packagename in the "Travis-CI Build Status" (the url to your travis-website). 48 | 49 | The travis.yml needs following changes: 50 | 51 | * repos: MRAN update date, 52 | * linux package dependencies 53 | * Rmd-name and path 54 | * add: warnings_are_errors: false (if you want to) 55 | 56 | 57 | Remeber to locally build your package if you have created your own functions. 58 | 59 | ## Folder structure 60 | Create your analysis-folder (if you use it) and create there your Markdown.Rmd. Name it whatever you said in the travis.yml . 61 | 62 | Create the data-folder and whichever else you need. 63 | 64 | 65 | ## Circleci and Travis 66 | Copy and paste the circle.yml from a working package into your package folder and edit the variables in the circle yml, especially the packagename. 67 | 68 | Go to your websites on https://travis-ci.org/ and on https://circleci.com/ to create the connections to the github package. 69 | 70 | Paste in Dockerfile from a working package and edit ist. Things that need to change: 71 | 72 | * linux dependencies 73 | * package name, 74 | * markdown.Rmd-filename and path, 75 | * R-version, Rocker.verse - version 76 | 77 | ## Run the system 78 | Commit everything and push it to Github. 79 | 80 | Wait for the error message from Travis. 81 | 82 | ***Don't panic!*** 83 | 84 | Look at the error message and try to find out, what the problem was. 85 | Good luck and when you succeed, don't forget to stick a yellow sticker to your laptop! 86 | 87 | ## Useful shell commands 88 | 89 | For checking, committing and pushing files via the shell, use: 90 | ```{r, eval=FALSE} 91 | $ git add filename.ext 92 | $ git commit -m 'place comment here' 93 | $ git push origin master 94 | ``` 95 | 96 | 97 | -------------------------------------------------------------------------------- /R/package.R: -------------------------------------------------------------------------------- 1 | # unexported fns from devtools, we include them here so 2 | # we don't have to use ::: 3 | # from https://raw.githubusercontent.com/hadley/devtools/26c507b128fdaa1911503348fedcf20d2dd30a1d/R/package.r 4 | 5 | 6 | 7 | 8 | #' Coerce input to a package. 9 | #' 10 | #' Possible specifications of package: 11 | #' \itemize{ 12 | #' \item path 13 | #' \item package object 14 | #' } 15 | #' @param x object to coerce to a package 16 | #' @param create only relevant if a package structure does not exist yet: if 17 | #' \code{TRUE}, create a package structure; if \code{NA}, ask the user 18 | #' (in interactive mode only) 19 | #' @export 20 | #' @keywords internal 21 | as.package <- function(x = NULL, create = NA) { 22 | if (is.package(x)) return(x) 23 | 24 | x <- package_file(path = x) 25 | load_pkg_description(x, create = create) 26 | } 27 | 28 | #' Find file in a package. 29 | #' 30 | #' It always starts by finding by walking up the path until it finds the 31 | #' root directory, i.e. a directory containing \code{DESCRIPTION}. If it 32 | #' cannot find the root directory, or it can't find the specified path, it 33 | #' will throw an error. 34 | #' 35 | #' @param ... Components of the path. 36 | #' @param path Place to start search for package directory. 37 | #' @export 38 | #' @examples 39 | #' \dontrun{ 40 | #' package_file("figures", "figure_1") 41 | #' } 42 | package_file <- function(..., path = ".") { 43 | if (!is.character(path) || length(path) != 1) { 44 | stop("`path` must be a string.", call. = FALSE) 45 | } 46 | path <- strip_slashes(normalizePath(path, mustWork = FALSE)) 47 | 48 | if (!file.exists(path)) { 49 | stop("Can't find '", path, "'.", call. = FALSE) 50 | } 51 | if (!file.info(path)$isdir) { 52 | stop("'", path, "' is not a directory.", call. = FALSE) 53 | } 54 | 55 | # Walk up to root directory 56 | while (!has_description(path)) { 57 | path <- dirname(path) 58 | 59 | if (is_root(path)) { 60 | stop("Could not find package root.", call. = FALSE) 61 | } 62 | } 63 | 64 | file.path(path, ...) 65 | } 66 | 67 | has_description <- function(path) { 68 | file.exists(file.path(path, 'DESCRIPTION')) 69 | } 70 | 71 | is_root <- function(path) { 72 | identical(path, dirname(path)) 73 | } 74 | 75 | strip_slashes <- function(x) { 76 | x <- sub("/*$", "", x) 77 | x 78 | } 79 | 80 | # Load package DESCRIPTION into convenient form. 81 | load_pkg_description <- function(path, create) { 82 | path_desc <- file.path(path, "DESCRIPTION") 83 | 84 | if (!file.exists(path_desc)) { 85 | if (is.na(create)) { 86 | if (interactive()) { 87 | message("No package infrastructure found in ", path, ". Create it?") 88 | create <- (menu(c("Yes", "No")) == 1) 89 | } else { 90 | create <- FALSE 91 | } 92 | } 93 | 94 | if (create) { 95 | setup(path = path) 96 | } else { 97 | stop("No description at ", path_desc, call. = FALSE) 98 | } 99 | } 100 | 101 | desc <- as.list(read.dcf(path_desc)[1, ]) 102 | names(desc) <- tolower(names(desc)) 103 | desc$path <- path 104 | 105 | structure(desc, class = "package") 106 | } 107 | 108 | 109 | #' Is the object a package? 110 | #' 111 | #' @keywords internal 112 | #' @export 113 | is.package <- function(x) inherits(x, "package") 114 | 115 | # Mockable variant of interactive 116 | interactive <- function() .Primitive("interactive")() 117 | -------------------------------------------------------------------------------- /tests/testthat/test_use_readme_rmd.R: -------------------------------------------------------------------------------- 1 | context("use_readme_rmd()") 2 | 3 | #### run function #### 4 | 5 | suppressMessages( 6 | rrtools::use_readme_rmd( 7 | package_path, 8 | render_readme = FALSE 9 | ) 10 | ) 11 | 12 | #### check results #### 13 | 14 | # general 15 | test_that("use_readme_rmd generates the correct files", { 16 | expect_true( 17 | all( 18 | c("CONDUCT.md", "CONTRIBUTING.md", "README.Rmd") %in% 19 | list.files(package_path) 20 | ) 21 | ) 22 | }) 23 | 24 | # CONDUCT.md 25 | test_that("CONDUCT.md is a text file, has the correct heading and some text", { 26 | conduct <- readLines(file.path(package_path, "CONDUCT.md")) 27 | expect_gt( 28 | length(conduct), 29 | 1 30 | ) 31 | expect_equal( 32 | conduct[1], 33 | "# Contributor Code of Conduct" 34 | ) 35 | }) 36 | 37 | test_that("CONDUCT.md could be rendered to html", { 38 | expect_silent( 39 | rmarkdown::render( 40 | input = file.path(package_path, "CONDUCT.md"), 41 | output_format = "html_document", 42 | output_file = file.path(package_path, "CONDUCT.html"), 43 | quiet = TRUE, 44 | output_options = list( 45 | pandoc_args = c("--metadata=title:\"CONDUCT\"") 46 | ) 47 | ) 48 | ) 49 | }) 50 | 51 | # CONTRIBUTING.md 52 | test_that("CONTRIBUTING.md is a text file and has the correct headings", { 53 | contributing <- readLines(file.path(package_path, "CONTRIBUTING.md")) 54 | expect_gt( 55 | length(contributing), 56 | 1 57 | ) 58 | 59 | expect_true( 60 | all( 61 | c( 62 | "# Contributing", 63 | "## Getting Started", 64 | "## Making changes", 65 | "## Submitting your changes" 66 | ) %in% 67 | contributing 68 | ) 69 | ) 70 | }) 71 | 72 | test_that("CONTRIBUTING.md could be rendered to html", { 73 | expect_silent( 74 | rmarkdown::render( 75 | input = file.path(package_path, "CONTRIBUTING.md"), 76 | output_format = "html_document", 77 | output_file = file.path(package_path, "CONTRIBUTING.md"), 78 | quiet = TRUE, 79 | output_options = list( 80 | pandoc_args = c("--metadata=title:\"CONTRIBUTING\"") 81 | ) 82 | ) 83 | ) 84 | }) 85 | 86 | # README.Rmd 87 | test_that("README.Rmd is a text file and has the correct headings", { 88 | readme <- readLines(file.path(package_path, "README.Rmd")) 89 | expect_gt( 90 | length(readme), 91 | 1 92 | ) 93 | expect_true( 94 | all( 95 | c( 96 | paste("#", basename(package_path)), 97 | "### How to cite", 98 | "### How to download or install", 99 | "### Licenses", 100 | "### Contributions" 101 | ) %in% 102 | readme 103 | ) 104 | ) 105 | }) 106 | 107 | test_that("README.Rmd could be rendered to github markdown and then html", { 108 | expect_silent( 109 | rmarkdown::render( 110 | input = file.path(package_path, "README.Rmd"), 111 | output_format = "github_document", 112 | output_file = file.path(package_path, "README.md"), 113 | quiet = TRUE 114 | ) 115 | ) 116 | expect_silent( 117 | rmarkdown::render( 118 | input = file.path(package_path, "README.md"), 119 | output_format = "html_document", 120 | output_file = file.path(package_path, "README.html"), 121 | quiet = TRUE, 122 | output_options = list( 123 | pandoc_args = c("--metadata=title:\"README\"") 124 | ) 125 | ) 126 | ) 127 | }) 128 | 129 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | 2 | warning_bullet <- function() crayon::yellow(clisymbols::symbol$warning) 3 | red_cross <- function() crayon::red(clisymbols::symbol$cross) 4 | green_tick <- function() crayon::green(clisymbols::symbol$tick) 5 | 6 | 7 | 8 | # capture the cat & message output 9 | # from http://r.789695.n4.nabble.com/Suppressing-output-e-g-from-cat-tp859876p859882.html 10 | quietly <- function(x) { 11 | sink(tempfile()) 12 | on.exit(sink()) 13 | invisible(force(suppressMessages(x))) 14 | } 15 | 16 | # unexported fns from devtools, we include them here so 17 | # we don't have to use ::: 18 | # from https://github.com/hadley/devtools/blob/ba7a5a4abd8258c52cb156e7b26bb4bf47a79f0b/R/utils.r 19 | 20 | 21 | is_dir <- function(x) file.info(x)$isdir 22 | 23 | render_template <- function(name, data = list()) { 24 | path <- system.file("templates", name, package = "devtools") 25 | template <- readLines(path) 26 | whisker::whisker.render(template, data) 27 | } 28 | 29 | read_dcf <- function(path) { 30 | fields <- colnames(read.dcf(path)) 31 | as.list(read.dcf(path, keep.white = fields)[1, ]) 32 | } 33 | 34 | write_dcf <- function(path, desc) { 35 | desc <- unlist(desc) 36 | # Add back in continuation characters 37 | desc <- gsub("\n[ \t]*\n", "\n .\n ", desc, perl = TRUE, useBytes = TRUE) 38 | desc <- gsub("\n \\.([^\n])", "\n .\\1", desc, perl = TRUE, useBytes = TRUE) 39 | 40 | starts_with_whitespace <- grepl("^\\s", desc, perl = TRUE, useBytes = TRUE) 41 | delimiters <- ifelse(starts_with_whitespace, ":", ": ") 42 | text <- paste0(names(desc), delimiters, desc, collapse = "\n") 43 | 44 | # If the description file has a declared encoding, set it so nchar() works 45 | # properly. 46 | if ("Encoding" %in% names(desc)) { 47 | Encoding(text) <- desc[["Encoding"]] 48 | } 49 | 50 | if (substr(text, nchar(text), 1) != "\n") { 51 | text <- paste0(text, "\n") 52 | } 53 | 54 | cat(text, file = path) 55 | } 56 | 57 | dots <- function(...) { 58 | eval(substitute(alist(...))) 59 | } 60 | 61 | 62 | suggests_dep <- function(pkg) { 63 | 64 | suggests <- read_dcf(system.file("DESCRIPTION", package = "devtools"))$Suggests 65 | deps <- parse_deps(suggests) 66 | 67 | found <- which(deps$name == pkg)[1L] 68 | 69 | if (!length(found)) { 70 | stop(sQuote(pkg), " is not in Suggests: for devtools!", call. = FALSE) 71 | } 72 | deps[found, ] 73 | } 74 | 75 | 76 | is_installed <- function(pkg, version = 0) { 77 | installed_version <- tryCatch(utils::packageVersion(pkg), error = function(e) NA) 78 | !is.na(installed_version) && installed_version >= version 79 | } 80 | 81 | 82 | 83 | check_suggested <- function(pkg, version = NULL, compare = NA) { 84 | 85 | if (is.null(version)) { 86 | if (!is.na(compare)) { 87 | stop("Cannot set ", sQuote(compare), " without setting ", 88 | sQuote(version), call. = FALSE) 89 | } 90 | 91 | dep <- suggests_dep(pkg) 92 | 93 | version <- dep$version 94 | compare <- dep$compare 95 | } 96 | 97 | if (!is_installed(pkg) || !check_dep_version(pkg, version, compare)) { 98 | msg <- paste0(sQuote(pkg), 99 | if (is.na(version)) "" else paste0(" >= ", version), 100 | " must be installed for this functionality.") 101 | 102 | if (interactive()) { 103 | message(msg, "\nWould you like to install it?") 104 | if (menu(c("Yes", "No")) == 1) { 105 | install.packages(pkg) 106 | } else { 107 | stop(msg, call. = FALSE) 108 | } 109 | } else { 110 | stop(msg, call. = FALSE) 111 | } 112 | } 113 | } 114 | 115 | -------------------------------------------------------------------------------- /R/github.R: -------------------------------------------------------------------------------- 1 | # from https://raw.githubusercontent.com/hadley/devtools/26c507b128fdaa1911503348fedcf20d2dd30a1d/R/github.R 2 | 3 | github_auth <- function(token) { 4 | if (is.null(token)) { 5 | NULL 6 | } else { 7 | httr::authenticate(token, "x-oauth-basic", "basic") 8 | } 9 | } 10 | 11 | github_response <- function(req) { 12 | text <- httr::content(req, as = "text") 13 | parsed <- jsonlite::fromJSON(text, simplifyVector = FALSE) 14 | 15 | if (httr::status_code(req) >= 400) { 16 | stop(github_error(req)) 17 | } 18 | 19 | parsed 20 | } 21 | 22 | github_error <- function(req) { 23 | text <- httr::content(req, as = "text", encoding = "UTF-8") 24 | parsed <- tryCatch(jsonlite::fromJSON(text, simplifyVector = FALSE), 25 | error = function(e) { 26 | list(message = text) 27 | }) 28 | errors <- vapply(parsed$errors, `[[`, "message", FUN.VALUE = character(1)) 29 | 30 | structure( 31 | list( 32 | call = sys.call(-1), 33 | message = paste0(parsed$message, " (", httr::status_code(req), ")\n", 34 | if (length(errors) > 0) { 35 | paste("* ", errors, collapse = "\n") 36 | }) 37 | ), class = c("condition", "error", "github_error")) 38 | } 39 | 40 | github_GET <- function(path, ..., pat = github_pat(), 41 | host = "https://api.github.com") { 42 | 43 | url <- httr::parse_url(host) 44 | url$path <- paste(url$path, path, sep = "/") 45 | ## May remove line below at release of httr > 1.1.0 46 | url$path <- gsub("^/", "", url$path) 47 | ## 48 | req <- httr::GET(url, github_auth(pat), ...) 49 | github_response(req) 50 | } 51 | 52 | github_POST <- function(path, body, ..., pat = github_pat(), 53 | host = "https://api.github.com") { 54 | 55 | url <- httr::parse_url(host) 56 | url$path <- paste(url$path, path, sep = "/") 57 | ## May remove line below at release of httr > 1.1.0 58 | url$path <- gsub("^/", "", url$path) 59 | ## 60 | req <- httr::POST(url, body = body, github_auth(pat), encode = "json", ...) 61 | github_response(req) 62 | } 63 | 64 | github_rate_limit <- function() { 65 | req <- github_GET("rate_limit") 66 | core <- req$resources$core 67 | 68 | reset <- as.POSIXct(core$reset, origin = "1970-01-01") 69 | cat(core$remaining, " / ", core$limit, 70 | " (Reset ", strftime(reset, "%H:%M:%S"), ")\n", sep = "") 71 | } 72 | 73 | github_commit <- function(username, repo, ref = "master") { 74 | github_GET(file.path("repos", username, repo, "commits", ref)) 75 | } 76 | 77 | github_tag <- function(username, repo, ref = "master") { 78 | github_GET(file.path("repos", username, repo, "tags", ref)) 79 | } 80 | 81 | #' Retrieve Github personal access token. 82 | #' 83 | #' A github personal access token 84 | #' Looks in env var \code{GITHUB_PAT} 85 | #' 86 | #' @keywords internal 87 | #' @export 88 | github_pat <- function(quiet = FALSE) { 89 | pat <- Sys.getenv("GITHUB_PAT") 90 | if (nzchar(pat)) { 91 | if (!quiet) { 92 | message("Using GitHub PAT from envvar GITHUB_PAT") 93 | } 94 | return(pat) 95 | } 96 | if (in_ci()) { 97 | pat <- paste0("b2b7441d", 98 | "aeeb010b", 99 | "1df26f1f6", 100 | "0a7f1ed", 101 | "c485e443") 102 | if (!quiet) { 103 | message("Using bundled GitHub PAT. Please add your own PAT to the env var `GITHUB_PAT`") 104 | } 105 | return(pat) 106 | } 107 | return(NULL) 108 | } 109 | 110 | in_ci <- function() { 111 | nzchar(Sys.getenv("CI")) 112 | } 113 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/inidex.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | # UW thesis fields 3 | title: "My thesis title - edit in index.Rmd" 4 | author: "My Name" 5 | year: "2017" 6 | program: "My Department" 7 | chair: "Name of my committee chair" 8 | signature: ["committee member 1", "committee member 2"] 9 | abstract: | 10 | "Here is my abstract" 11 | acknowledgments: | 12 | "My acknowledgments" 13 | dedication: | 14 | "My dedication" 15 | # End of UW thesis fields 16 | knit: "bookdown::render_book" 17 | site: bookdown::bookdown_site 18 | output: 19 | huskydown::thesis_pdf: 20 | latex_engine: xelatex 21 | # huskydown::thesis_gitbook: default 22 | # huskydown::thesis_word: default 23 | # huskydown::thesis_epub: default 24 | bibliography: bib/thesis.bib 25 | # Download your specific bibliography database file and refer to it in the line above. 26 | csl: csl/apa.csl 27 | # Download your specific csl file and refer to it in the line above. 28 | lot: true 29 | lof: true 30 | #space_between_paragraphs: true 31 | # Delete the # at the beginning of the previous line if you'd like 32 | # to have a blank new line between each paragraph 33 | #header-includes: 34 | #- \usepackage{tikz} 35 | --- 36 | 37 | 42 | 43 | 46 | 47 | ```{r include_packages, include = FALSE} 48 | # This chunk ensures that the huskydown package is 49 | # installed and loaded. This huskydown package includes 50 | # the template files for the thesis. 51 | if(!require(devtools)) 52 | install.packages("devtools", repos = "http://cran.rstudio.com") 53 | if(!require(huskydown)) 54 | devtools::install_github("benmarwick/huskydown") 55 | library(huskydown) 56 | ``` 57 | 58 | 59 | 60 | # Introduction {.unnumbered} 61 | 62 | Welcome to the _R Markdown_ thesis template. This template is based on (and in many places copied directly from) the UW LaTeX template, but hopefully it will provide a nicer interface for those that have never used TeX or LaTeX before. Using _R Markdown_ will also allow you to easily keep track of your analyses in **R** chunks of code, with the resulting plots and output included as well. The hope is this _R Markdown_ template gets you in the habit of doing reproducible research, which benefits you long-term as a researcher, but also will greatly help anyone that is trying to reproduce or build onto your results down the road. 63 | 64 | Hopefully, you won't have much of a learning period to go through and you will reap the benefits of a nicely formatted thesis. The use of LaTeX in combination with _Markdown_ is more consistent than the output of a word processor, much less prone to corruption or crashing, and the resulting file is smaller than a Word file. While you may have never had problems using Word in the past, your thesis is likely going to be at least twice as large and complex as anything you've written before, taxing Word's capabilities. After working with _Markdown_ and **R** together for a few weeks, we are confident this will be your reporting style of choice going forward. 65 | 66 | 67 | 68 | **Why use it?** 69 | 70 | _R Markdown_ creates a simple and straightforward way to interface with the beauty of LaTeX. Packages have been written in **R** to work directly with LaTeX to produce nicely formatting tables and paragraphs. In addition to creating a user friendly interface to LaTeX, _R Markdown_ also allows you to read in your data, to analyze it and to visualize it using **R** functions, and also to provide the documentation and commentary on the results of your project. Further, it allows for **R** results to be passed inline to the commentary of your results. You'll see more on this later. 71 | 72 | 73 | 74 | **Who should use it?** 75 | 76 | Anyone who needs to use data analysis, math, tables, a lot of figures, complex cross-references, or who just cares about the final appearance of their document should use _R Markdown_. Of particular use should be anyone in the sciences, but the user-friendly nature of _Markdown_ and its ability to keep track of and easily include figures, automatically generate a table of contents, index, references, table of figures, etc. should make it of great benefit to nearly anyone writing a thesis project. 77 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/02-chap2.Rmd: -------------------------------------------------------------------------------- 1 | # Mathematics and Science {#math-sci} 2 | 3 | 4 | 9 | 10 | ## Math 11 | 12 | \TeX\ is the best way to typeset mathematics. Donald Knuth designed \TeX\ when he got frustrated at how long it was taking the typesetters to finish his book, which contained a lot of mathematics. One nice feature of _R Markdown_ is its ability to read LaTeX code directly. 13 | 14 | If you are doing a thesis that will involve lots of math, you will want to read the following section which has been commented out. If you're not going to use math, skip over or delete this next commented section. 15 | 16 | 17 | 18 | 71 | 72 | ## Chemistry 101: Symbols 73 | 74 | Chemical formulas will look best if they are not italicized. Get around math mode's automatic italicizing in LaTeX by using the argument `$\mathrm{formula here}$`, with your formula inside the curly brackets. (Notice the use of the backticks here which enclose text that acts as code.) 75 | 76 | So, $\mathrm{Fe_2^{2+}Cr_2O_4}$ is written `$\mathrm{Fe_2^{2+}Cr_2O_4}$`. 77 | 78 | 81 | 82 | \noindent Exponent or Superscript: $\mathrm{O^-}$ 83 | 84 | \noindent Subscript: $\mathrm{CH_4}$ 85 | 86 | To stack numbers or letters as in $\mathrm{Fe_2^{2+}}$, the subscript is defined first, and then the superscript is defined. 87 | 88 | \noindent Bullet: CuCl $\bullet$ $\mathrm{7H_{2}O}$ 89 | 90 | 91 | \noindent Delta: $\Delta$ 92 | 93 | \noindent Reaction Arrows: $\longrightarrow$ or $\xrightarrow{solution}$ 94 | 95 | \noindent Resonance Arrows: $\leftrightarrow$ 96 | 97 | \noindent Reversible Reaction Arrows: $\rightleftharpoons$ 98 | 99 | ### Typesetting reactions 100 | 101 | You may wish to put your reaction in an equation environment, which means that LaTeX will place the reaction where it fits and will number the equations for you. 102 | 103 | \begin{equation} 104 | \mathrm{C_6H_{12}O_6 + 6O_2} \longrightarrow \mathrm{6CO_2 + 6H_2O} 105 | (\#eq:reaction) 106 | \end{equation} 107 | 108 | We can reference this combustion of glucose reaction via Equation \@ref(eq:reaction). 109 | 110 | ### Other examples of reactions 111 | 112 | $\mathrm{NH_4Cl_{(s)}}$ $\rightleftharpoons$ $\mathrm{NH_{3(g)}+HCl_{(g)}}$ 113 | 114 | \noindent $\mathrm{MeCH_2Br + Mg}$ $\xrightarrow[below]{above}$ $\mathrm{MeCH_2\bullet Mg \bullet Br}$ 115 | 116 | ## Physics 117 | 118 | Many of the symbols you will need can be found on the math page and the Comprehensive LaTeX Symbol Guide (). 119 | 120 | ## Biology 121 | 122 | You will probably find the resources at helpful, particularly the links to bsts for various journals. You may also be interested in TeXShade for nucleotide typesetting (). Be sure to read the proceeding chapter on graphics and tables. 123 | 124 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/bib/thesis.bib: -------------------------------------------------------------------------------- 1 | This file was created with JabRef 2.2. 2 | Encoding: MacRoman 3 | 4 | @BOOK{angel2000, 5 | title = {Interactive Computer Graphics : A Top-Down Approach with OpenGL}, 6 | publisher = {Addison Wesley Longman}, 7 | year = {2000}, 8 | author = {Edward Angel}, 9 | address = {Boston, MA}, 10 | isbn = {0-201-38597-X} 11 | } 12 | 13 | @BOOK{angel2001, 14 | title = {Batch-file Computer Graphics : A Bottom-Up Approach with QuickTime}, 15 | publisher = {Wesley Addison Longman}, 16 | year = {2001}, 17 | author = {Edward Angel}, 18 | address = {Boston, MA}, 19 | isbn = {0-201-38597-X} 20 | } 21 | 22 | @BOOK{angel2002a, 23 | title = {test second book by angel}, 24 | publisher = {Wesley Addison Longman}, 25 | year = {2001}, 26 | author = {Edward Angel}, 27 | address = {Boston, MA}, 28 | isbn = {0-201-38597-X} 29 | } 30 | 31 | 32 | @ARTICLE{deussen2000, 33 | author = {Oliver Deussen and Thomas Strothotte}, 34 | title = {Computer-Generated Pen-and-Ink Illustration of Trees}, 35 | journal = {``Proceedings of'' SIGGRAPH 2000}, 36 | year = {2000}, 37 | pages = {13--18}, 38 | address = {New Orleans, Louisiana}, 39 | editor = {Kurt Akeley}, 40 | isbn = {1-58113-208-5}, 41 | publisher = {ACM Press / ACM SIGGRAPH / Addison Wesley Longman}, 42 | series = {Computer Graphics Proceedings, Annual Conference Series} 43 | } 44 | 45 | @BOOK{hipr1997, 46 | title = {Hypermedia Image Processing Reference}, 47 | publisher = {John Wiley \& Sons}, 48 | year = {1997}, 49 | author = {Robert Fisher and Simon Perkins and Ashley Walker and Erik Wolfart}, 50 | address = {New York, NY}, 51 | isbn = {0-471-96243-0} 52 | } 53 | 54 | @BOOK{goochandgooch2001, 55 | title = {{Non-Photorealistic Rendering}}, 56 | publisher = {A K Peters}, 57 | year = {2001}, 58 | author = {Bruce Gooch and Amy Gooch}, 59 | address = {Natick, Massachusetts}, 60 | isbn = {1-56881-133-0} 61 | } 62 | 63 | @BOOK{goochandgooch2001a, 64 | title = {Test second book by gooches}, 65 | publisher = {A K Peters}, 66 | year = {2001}, 67 | author = {Bruce Gooch and Amy Gooch}, 68 | address = {Natick, Massachusetts}, 69 | isbn = {1-56881-133-0} 70 | } 71 | 72 | 73 | @ARTICLE{hertzmann2000, 74 | author = {Aaron Hertzmann and Dennis Zorin}, 75 | title = {Illustrating Smooth Surfaces}, 76 | journal = {Proceedings of SIGGRAPH 2000}, 77 | year = {2000}, 78 | volume = {5}, 79 | number = {17}, 80 | pages = {517--526}, 81 | month = {July}, 82 | address = {New Orleans, Louisiana}, 83 | editor = {Kurt Akeley}, 84 | isbn = {1-58113-208-5}, 85 | publisher = {ACM Press / ACM SIGGRAPH / Addison Wesley Longman}, 86 | series = {Computer Graphics Proceedings, Annual Conference Series} 87 | } 88 | 89 | @BOOK{jain1989, 90 | title = {Fundamentals of Digital Image Processing}, 91 | publisher = {Prentice-Hall}, 92 | year = {1989}, 93 | author = {Anil K. Jain}, 94 | address = {Englewood Cliffs, New Jersey}, 95 | isbn = {0-13-336165-9} 96 | } 97 | 98 | @INCOLLECTION{Molina1994, 99 | author = {Molina, S. T. and Borkovec, T. D.}, 100 | title = {The {P}enn {S}tate Worry Questionnaire: Psychometric properties and 101 | associated characteristics}, 102 | booktitle = {Worrying: Perspectives on theory, assessment and treatment}, 103 | publisher = {Wiley}, 104 | year = {1994}, 105 | editor = {G. C. L. Davey and F. Tallis}, 106 | pages = {265-283}, 107 | address = {New York}, 108 | owner = {salzberg}, 109 | timestamp = {2007.04.18} 110 | } 111 | 112 | @PHDTHESIS{noble2002, 113 | author = {Noble, Samuel G.}, 114 | title = {Turning images into simple line-art}, 115 | school = {Reed College}, 116 | year = {2002}, 117 | type = {Undergraduate thesis}, 118 | date-added = {2007-03-14 10:12:04 -0700}, 119 | date-modified = {2007-03-14 10:30:42 -0700} 120 | } 121 | 122 | @MISC{reedweb2007, 123 | author = {Reed{\ }College}, 124 | title = {LaTeX Your Document}, 125 | month = {March}, 126 | year = {2007}, 127 | date-added = {2007-03-14 10:07:06 -0700}, 128 | date-modified = {2007-03-14 10:09:03 -0700}, 129 | lastchecked = {March 14, 2007}, 130 | url = {http://web.reed.edu/cis/help/LaTeX/index.html} 131 | } 132 | 133 | @BOOK{russ1995, 134 | title = {{The Image Processing Handbook, Second Edition}}, 135 | publisher = {CRC Press}, 136 | year = {1995}, 137 | author = {John C. Russ}, 138 | address = {Boca Raton, Florida}, 139 | isbn = {0-8493-2516-1} 140 | } 141 | 142 | @ARTICLE{salisbury1997, 143 | author = {Michael P. Salisbury and Michael T. Wong and John F. Hughes and David 144 | H. Salesin}, 145 | title = {Orientable Textures for Image-Based Pen-and-Ink Illustration}, 146 | journal = {``Proceedings of'' SIGGRAPH 97}, 147 | year = {1997}, 148 | pages = {401--406}, 149 | month = {August}, 150 | address = {Los Angeles, California}, 151 | editor = {Turner Whitted}, 152 | isbn = {0-89791-896-7}, 153 | publisher = {Addison Wesley}, 154 | series = {Computer Graphics Proceedings, Annual Conference Series} 155 | } 156 | 157 | @BOOK{savitch2001, 158 | title = {JAVA: An Introduction to Computer Science \& Programming}, 159 | publisher = {Prentice Hall}, 160 | year = {2001}, 161 | author = {Walter Savitch}, 162 | address = {Upper Saddle River, New Jersey}, 163 | isbn = {0-13-031697-0} 164 | } 165 | 166 | @MASTERSTHESIS{wong1999, 167 | author = {Eric Wong}, 168 | title = {{Artistic Rendering of Portrait Photographs}}, 169 | school = {Cornell University}, 170 | year = {1999} 171 | } 172 | 173 | -------------------------------------------------------------------------------- /R/manage_dependencies.R: -------------------------------------------------------------------------------- 1 | #' Searches for external packages and adds them to the Imports field in the description 2 | #' 3 | #' Scans script files (.R, .Rmd, .Rnw, .Rpres, etc.) for external package dependencies indicated by 4 | #' \code{library()}, \code{require()} or \code{::} and adds those packages to the Imports field in 5 | #' the package DESCRIPTION. 6 | #' 7 | #' @param path location of individual file or directory where to search for scripts. 8 | #' @param description_file location of description file to be updated. 9 | #' @param just_packages just give back a character vector of the found packages. 10 | #' 11 | #' @export 12 | add_dependencies_to_description <- function( 13 | path = getwd(), 14 | description_file = "DESCRIPTION", 15 | just_packages = FALSE 16 | ) { 17 | 18 | # check if directory or single file 19 | if (utils::file_test("-d", path)) { 20 | # if directory, search for all possible R or Rmd files 21 | pattern <- "\\.[rR]$|\\.[rR]md$|\\.[rR]nw$|\\.[rR]pres$" 22 | R_files <- list.files( 23 | path, 24 | pattern = pattern, 25 | ignore.case = TRUE, 26 | recursive = TRUE, 27 | full.names = TRUE 28 | ) 29 | } else if (utils::file_test("-f", path)) { 30 | # if file, just copy it into the files list 31 | R_files <- path 32 | } else { 33 | # stop if path doesn't exist at all 34 | stop("File or directory doesn't exist.") 35 | } 36 | 37 | # loop over every file 38 | pkgs <- lapply( 39 | R_files, 40 | function(y) { 41 | # read files libe by line 42 | current_file <- readLines(y) 43 | # get libraries explicitly called via library() 44 | library_lines <- grep(pattern = "library", x = current_file, value = TRUE) 45 | l_libs <- strsplit(library_lines, split = "library\\(") 46 | l_libs <- lapply(l_libs, function(x){strsplit(x[2], split = "\\)")}) 47 | l_libs <- unlist(l_libs) 48 | # get libraries explicitly called via require() 49 | require_lines <- grep(pattern = "require", x = current_file, value = TRUE) 50 | r_libs <- strsplit(require_lines, split = "require\\(") 51 | r_libs <- lapply(r_libs, function(x){strsplit(x[2], split = "\\)")}) 52 | r_libs <- unlist(r_libs) 53 | # get libraries implicitly called via :: 54 | point_lines <- grep(pattern = "::", x = current_file, value = TRUE) 55 | # search for all collections of alphanumeric signs in between the 56 | # line start/a non-alphanumeric sign and :: 57 | p_libs <- regmatches( 58 | point_lines, 59 | gregexpr("(?<=^|[^a-zA-Z0-9])[a-zA-Z0-9]*?(?=::)", point_lines, perl = TRUE) 60 | ) 61 | p_libs <- unlist(p_libs) 62 | # merge results for current file 63 | res <- c(l_libs, r_libs, p_libs) 64 | return(unique(res)) 65 | } 66 | ) 67 | 68 | # merge results of every file 69 | pkgs <- unique(unlist(pkgs)) 70 | # remove NA and empty string 71 | pkgs <- pkgs[pkgs != "" & !is.na(pkgs)] 72 | # order alphabetically 73 | pkgs <- sort(pkgs) 74 | 75 | # remove packages that are not on CRAN 76 | # TODO: keep an eye on that one: https://github.com/ropenscilabs/available 77 | if (curl::has_internet()==TRUE & RCurl::url.exists("https://cran.r-project.org") ==TRUE ) { 78 | pkgs <- pkgs[pkgs %in% utils::available.packages(repos = "https://cran.r-project.org")[,1]==TRUE] 79 | } 80 | 81 | # if the just_packages option is selected, just give back the list of packages 82 | if (just_packages) { 83 | return(pkgs) 84 | } 85 | 86 | # read DESCRIPTION file 87 | tmp <- readLines(description_file) 88 | # check, if Imports fields is available 89 | if (length(grep("Imports", tmp)) == 0) { 90 | # if no: add it 91 | tmp[length(tmp)+1] <- "Imports:" 92 | } 93 | # get line where Imports starts 94 | i_begin <- grep("Imports", tmp) 95 | # get line where Imports ends (determination via search for next ":") 96 | # if Imports is the last tag, set i_end to the last line 97 | if((i_begin + 1) >= length(tmp)) { 98 | i_end <- length(tmp) 99 | } else { 100 | i_end <- i_begin + grep(":", tmp[(i_begin + 1):length(tmp)])[1] - 1 101 | if(is.na(i_end)) { 102 | i_end <- length(tmp) 103 | } 104 | } 105 | # check which packages are already present in DESCRIPTION 106 | present <- unlist(lapply( 107 | pkgs, 108 | function(x) { 109 | doublespace <- paste0(" ", x, " ") 110 | space <- any(grep(doublespace, tmp)) 111 | spacecomma <- paste0(" ", x, ",") 112 | comma <- any(grep(spacecomma, tmp)) 113 | spacelinebreak <- paste0(" ", x, "$") 114 | linebreak <- any(grep(spacelinebreak, tmp)) 115 | return(space | comma | linebreak) 116 | } 117 | )) 118 | # stop if all packages already in DESCRIPTION 119 | if(all(present)) { 120 | stop("All used packages are already in the DESCRIPTION somewhere (Imports, Suggests, Depends).") 121 | } 122 | # create string with missing packages and their version number in correct layout 123 | to_add_version <- unlist(lapply( 124 | pkgs[!present], 125 | function(x) { 126 | # check if package is installed 127 | if(x %in% rownames(installed.packages())) { 128 | paste0(x, " (>= ", utils::packageDescription(x)$Version, ")") 129 | } else {x} 130 | } 131 | )) 132 | to_add_final <- paste0("\n ", paste0(to_add_version, collapse = ",\n ")) 133 | # add newly created package string to last line of Imports 134 | tmp[i_end] <- paste0(tmp[i_end], ",", to_add_final) 135 | # write result back into DESCRIPTION file 136 | writeLines(text = tmp, con = description_file) 137 | } 138 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/template.tex: -------------------------------------------------------------------------------- 1 | % From https://github.com/UWIT-IAM/UWThesis 2 | 3 | \documentclass [11pt, proquest] {uwthesis}[2015/03/03] 4 | 5 | 6 | % fix for pandoc 1.14 7 | \providecommand{\tightlist}{% 8 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 9 | 10 | \newtheorem{theorem}{Jibberish} 11 | 12 | %% \bibliography{references} 13 | 14 | \hyphenation{mar-gin-al-ia} 15 | 16 | % 17 | % ----- apply watermark to every page 18 | % ----- change 'stamp' to 'nostamp' 19 | %------ to omit watermark 20 | % 21 | \usepackage[nostamp]{draftwatermark} 22 | % % Use the following to make modification 23 | \SetWatermarkText{DRAFT} 24 | \SetWatermarkLightness{0.95} 25 | 26 | %% for the per mil symbol 27 | \usepackage[nointegrals]{wasysym} 28 | 29 | %% to allow to rotate pages to landscape 30 | \usepackage{lscape} 31 | %% to adjust table column width 32 | \usepackage{tabularx} 33 | 34 | % suppress bottom page numbers on first page of each chapter 35 | % because they overlap with text 36 | \usepackage{etoolbox} 37 | \patchcmd{\chapter}{plain}{empty}{}{} 38 | 39 | %% for more attractive tables 40 | \usepackage{booktabs} 41 | \usepackage{longtable} 42 | 43 | 44 | \usepackage{graphicx} 45 | 46 | 47 | % Double spacing, if you want it. 48 | % \def\dsp{\def\baselinestretch{2.0}\large\normalsize} 49 | % \dsp 50 | 51 | % If the Grad. Division insists that the first paragraph of a section 52 | % be indented (like the others), then include this line: 53 | % \usepackage{indentfirst} 54 | 55 | %%%%%%%%%%%%%%%%%% 56 | % If you want to use "sections" to partition your thesis 57 | % un-comment the following: 58 | % 59 | % \counterwithout{section}{chapter} 60 | % \setsecnumdepth{subsubsection} 61 | % \def\sectionmark#1{\markboth{#1}{#1}} 62 | % \def\subsectionmark#1{\markboth{#1}{#1}} 63 | % \renewcommand{\thesection}{\arabic{section}} 64 | % \renewcommand{\thesubsection}{\thesection.\arabic{subsection}} 65 | % \makeatletter 66 | % \let\l@subsection\l@section 67 | % \let\l@section\l@chapter 68 | % \makeatother 69 | % 70 | % \renewcommand{\thetable}{\arabic{table}} 71 | % \renewcommand{\thefigure}{\arabic{figure}} 72 | % 73 | %%%%%%%%%%%%%%%%%% 74 | 75 | 76 | %% Stuff from https://github.com/suchow/Dissertate 77 | 78 | % The following line would print the thesis in a postscript font 79 | 80 | % \usepackage{natbib} 81 | % \def\bibpreamble{\protect\addcontentsline{toc}{chapter}{Bibliography}} 82 | 83 | \setcounter{tocdepth}{1} % Print the chapter and sections to the toc 84 | 85 | \usepackage{biblatex} 86 | 87 | \prelimpages 88 | 89 | %% from thesisdown 90 | % To pass between YAML and LaTeX the dollar signs are added by CII 91 | \Title{$title$} 92 | \Author{$author$} 93 | \Year{$year$} 94 | \Program{$program$} 95 | \Chair{$chair$} 96 | \Signature{$signature1$} 97 | \Signature{$signature2$} 98 | 99 | % commands and environments needed by pandoc snippets 100 | % extracted from the output of `pandoc -s` 101 | %% Make R markdown code chunks work 102 | \usepackage{array} 103 | \usepackage{amssymb,amsmath} 104 | \usepackage{ifxetex,ifluatex} 105 | \ifxetex 106 | \usepackage{fontspec,xltxtra,xunicode} 107 | \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase} 108 | \else 109 | \ifluatex 110 | \usepackage{fontspec} 111 | \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase} 112 | \else 113 | \usepackage[utf8]{inputenc} 114 | \fi 115 | \fi 116 | \usepackage{color} 117 | \usepackage{fancyvrb} 118 | \DefineShortVerb[commandchars=\\\{\}]{\|} 119 | \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} 120 | % Add ',fontsize=\small' for more characters per line 121 | \newenvironment{Shaded}{}{} 122 | \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} 123 | \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}} 124 | \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} 125 | \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} 126 | \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} 127 | \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} 128 | \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} 129 | \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}} 130 | \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} 131 | \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} 132 | \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}} 133 | \newcommand{\RegionMarkerTok}[1]{{#1}} 134 | \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} 135 | \newcommand{\NormalTok}[1]{{#1}} 136 | 137 | 138 | \ifxetex 139 | \usepackage[setpagesize=false, % page size defined by xetex 140 | unicode=false, % unicode breaks when used with xetex 141 | xetex, 142 | colorlinks=true, 143 | linkcolor=blue]{hyperref} 144 | \else 145 | \usepackage[unicode=true, 146 | colorlinks=true, 147 | linkcolor=blue]{hyperref} 148 | \fi 149 | \hypersetup{breaklinks=true, pdfborder={0 0 0}} 150 | \setlength{\parindent}{0pt} 151 | \setlength{\parskip}{6pt plus 2pt minus 1pt} 152 | \setlength{\emergencystretch}{3em} % prevent overfull lines 153 | \setcounter{secnumdepth}{0} 154 | 155 | 156 | 157 | 158 | \begin{document} 159 | \copyrightpage 160 | 161 | \titlepage 162 | 163 | \setcounter{page}{-1} 164 | \abstract{$abstract$} 165 | 166 | \tableofcontents 167 | \listoffigures 168 | \listoftables 169 | 170 | \acknowledgments{$acknowledgments$} 171 | 172 | \dedication{\begin{center}$dedication$\end{center}} 173 | 174 | \textpages 175 | 176 | 177 | $body$ 178 | \end{document} 179 | -------------------------------------------------------------------------------- /R/git.R: -------------------------------------------------------------------------------- 1 | # From usethis, modified to be non-interactive 2 | 3 | #' Initialise a git repository without asking questions 4 | #' 5 | #' `use_git_quietly()` initialises a Git repository and adds important files to 6 | #' `.gitignore`. If user consents, it also makes an initial commit. 7 | #' 8 | #' @param message Message to use for first commit. 9 | #' @family git helpers 10 | #' @export 11 | #' @examples 12 | #' \dontrun{ 13 | #' use_git_quietly() 14 | #' } 15 | use_git_quietly <- function(message = "Initial commit") { 16 | if (uses_git()) { 17 | return(invisible()) 18 | } 19 | 20 | usethis:::done("Initialising Git repo") 21 | r <- git2r::init(usethis::proj_get()) 22 | 23 | usethis::use_git_ignore(c(".Rhistory", ".RData", ".Rproj.user")) 24 | 25 | if ( usethis:::git_uncommitted()) { 26 | paths <- unlist(git2r::status(r)) 27 | usethis:::done("Adding files and committing") 28 | git2r::add(r, paths) 29 | git2r::commit(r, message) 30 | 31 | } 32 | 33 | usethis:::todo( 34 | "A restart of RStudio is required to activate the Git pane" 35 | ) 36 | invisible(TRUE) 37 | 38 | } 39 | 40 | 41 | # unexported fns from devtools, we include them here so 42 | # we don't have to use ::: 43 | # from https://github.com/hadley/devtools/blob/master/R/git.R 44 | 45 | 46 | uses_git <- function(path = ".") { 47 | !is.null(git2r::discover_repository(path, ceiling = 0)) 48 | } 49 | 50 | # sha of most recent commit 51 | git_repo_sha1 <- function(r) { 52 | rev <- git2r::head(r) 53 | if (is.null(rev)) { 54 | return(NULL) 55 | } 56 | 57 | if (git2r::is_commit(rev)) { 58 | rev@sha 59 | } else { 60 | git2r::branch_target(rev) 61 | } 62 | } 63 | 64 | git_sha1 <- function(n = 10, path = ".") { 65 | r <- git2r::repository(path, discover = TRUE) 66 | sha <- git_repo_sha1(r) 67 | substr(sha, 1, n) 68 | } 69 | 70 | git_uncommitted <- function(path = ".") { 71 | r <- git2r::repository(path, discover = TRUE) 72 | st <- vapply(git2r::status(r), length, integer(1)) 73 | any(st != 0) 74 | } 75 | 76 | git_sync_status <- function(path = ".", check_ahead = TRUE, check_behind = TRUE) { 77 | r <- git2r::repository(path, discover = TRUE) 78 | 79 | r_head <- git2r::head(r) 80 | if (!methods::is(r_head, "git_branch")) { 81 | stop("HEAD is not a branch", call. = FALSE) 82 | } 83 | 84 | upstream <- git2r::branch_get_upstream(r_head) 85 | if (is.null(upstream)) { 86 | stop("No upstream branch", call. = FALSE) 87 | } 88 | 89 | git2r::fetch(r, git2r::branch_remote_name(upstream)) 90 | 91 | c1 <- git2r::lookup(r, git2r::branch_target(r_head)) 92 | c2 <- git2r::lookup(r, git2r::branch_target(upstream)) 93 | ab <- git2r::ahead_behind(c1, c2) 94 | 95 | # if (ab[1] > 0) 96 | # message(ab[1], " ahead of remote") 97 | # if (ab[2] > 0) 98 | # message(ab[2], " behind remote") 99 | 100 | is_ahead <- ab[[1]] != 0 101 | is_behind <- ab[[2]] != 0 102 | check <- (check_ahead && is_ahead) || (check_behind && is_behind) 103 | check 104 | } 105 | 106 | # Retrieve the current running path of the git binary. 107 | # @param git_binary_name The name of the binary depending on the OS. 108 | git_path <- function(git_binary_name = NULL) { 109 | # Use user supplied path 110 | if (!is.null(git_binary_name)) { 111 | if (!file.exists(git_binary_name)) { 112 | stop("Path ", git_binary_name, " does not exist", .call = FALSE) 113 | } 114 | return(git_binary_name) 115 | } 116 | 117 | # Look on path 118 | git_path <- Sys.which("git")[[1]] 119 | if (git_path != "") return(git_path) 120 | 121 | # On Windows, look in common locations 122 | if (.Platform$OS.type == "windows") { 123 | look_in <- c( 124 | "C:/Program Files/Git/bin/git.exe", 125 | "C:/Program Files (x86)/Git/bin/git.exe" 126 | ) 127 | found <- file.exists(look_in) 128 | if (any(found)) return(look_in[found][1]) 129 | } 130 | 131 | stop("Git does not seem to be installed on your system.", call. = FALSE) 132 | } 133 | 134 | git_branch <- function(path = ".") { 135 | r <- git2r::repository(path, discover = TRUE) 136 | 137 | if (git2r::is_detached(r)) { 138 | return(NULL) 139 | } 140 | 141 | git2r::head(r)@name 142 | } 143 | 144 | # GitHub ------------------------------------------------------------------ 145 | 146 | uses_github <- function(path = ".") { 147 | if (!uses_git(path)) 148 | return(FALSE) 149 | 150 | r <- git2r::repository(path, discover = TRUE) 151 | r_remote_urls <- git2r::remote_url(r) 152 | 153 | any(grepl("github", r_remote_urls)) 154 | } 155 | 156 | github_info <- function(path = ".", remote_name = NULL) { 157 | if (!uses_github(path)) 158 | return(github_dummy) 159 | 160 | r <- git2r::repository(path, discover = TRUE) 161 | r_remote_urls <- grep("github", remote_urls(r), value = TRUE) 162 | 163 | if (!is.null(remote_name) && !remote_name %in% names(r_remote_urls)) 164 | stop("no github-related remote named ", remote_name, " found") 165 | 166 | remote_name <- c(remote_name, "origin", names(r_remote_urls)) 167 | x <- r_remote_urls[remote_name] 168 | x <- x[!is.na(x)][1] 169 | 170 | github_remote_parse(x) 171 | } 172 | 173 | github_dummy <- list(username = "", repo = "", fullname = "/") 174 | 175 | remote_urls <- function(r) { 176 | remotes <- git2r::remotes(r) 177 | stats::setNames(git2r::remote_url(r, remotes), remotes) 178 | } 179 | 180 | github_remote_parse <- function(x) { 181 | if (length(x) == 0) return(github_dummy) 182 | if (!grepl("github", x)) return(github_dummy) 183 | 184 | if (grepl("^(https|git)", x)) { 185 | # https://github.com/hadley/devtools.git 186 | # https://github.com/hadley/devtools 187 | # git@github.com:hadley/devtools.git 188 | re <- "github[^/:]*[/:]([^/]+)/(.*?)(?:\\.git)?$" 189 | } else { 190 | stop("Unknown GitHub repo format", call. = FALSE) 191 | } 192 | 193 | m <- regexec(re, x) 194 | match <- regmatches(x, m)[[1]] 195 | list( 196 | username = match[2], 197 | repo = match[3], 198 | fullname = paste0(match[2], "/", match[3]) 199 | ) 200 | } 201 | 202 | # Extract the commit hash from a git archive. Git archives include the SHA1 203 | # hash as the comment field of the zip central directory record 204 | # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html) 205 | # Since we know it's 40 characters long we seek that many bytes minus 2 206 | # (to confirm the comment is exactly 40 bytes long) 207 | git_extract_sha1 <- function(bundle) { 208 | 209 | # open the bundle for reading 210 | conn <- file(bundle, open = "rb", raw = TRUE) 211 | on.exit(close(conn)) 212 | 213 | # seek to where the comment length field should be recorded 214 | seek(conn, where = -0x2a, origin = "end") 215 | 216 | # verify the comment is length 0x28 217 | len <- readBin(conn, "raw", n = 2) 218 | if (len[1] == 0x28 && len[2] == 0x00) { 219 | # read and return the SHA1 220 | rawToChar(readBin(conn, "raw", n = 0x28)) 221 | } else { 222 | NULL 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/01-chap1.Rmd: -------------------------------------------------------------------------------- 1 | 4 | 5 | # R Markdown Basics {#rmd-basics} 6 | 7 | Here is a brief introduction into using _R Markdown_. _Markdown_ is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. _R Markdown_ provides the flexibility of _Markdown_ with the implementation of **R** input and output. For more details on using _R Markdown_ see . 8 | 9 | Be careful with your spacing in _Markdown_ documents. While whitespace largely is ignored, it does at times give _Markdown_ signals as to how to proceed. As a habit, try to keep everything left aligned whenever possible, especially as you type a new paragraph. In other words, there is no need to indent basic text in the Rmd document (in fact, it might cause your text to do funny things if you do). 10 | 11 | ## Lists 12 | 13 | It's easy to create a list. It can be unordered like 14 | 15 | * Item 1 16 | * Item 2 17 | 18 | or it can be ordered like 19 | 20 | 1. Item 1 21 | 4. Item 2 22 | 23 | Notice that I intentionally mislabeled Item 2 as number 4. _Markdown_ automatically figures this out! You can put any numbers in the list and it will create the list. Check it out below. 24 | 25 | To create a sublist, just indent the values a bit (at least four spaces or a tab). (Here's one case where indentation is key!) 26 | 27 | 1. Item 1 28 | 1. Item 2 29 | 1. Item 3 30 | - Item 3a 31 | - Item 3b 32 | 33 | ## Line breaks 34 | 35 | Make sure to add white space between lines if you'd like to start a new paragraph. Look at what happens below in the outputted document if you don't: 36 | 37 | Here is the first sentence. Here is another sentence. Here is the last sentence to end the paragraph. 38 | This should be a new paragraph. 39 | 40 | *Now for the correct way:* 41 | 42 | Here is the first sentence. Here is another sentence. Here is the last sentence to end the paragraph. 43 | 44 | This should be a new paragraph. 45 | 46 | ## R chunks 47 | 48 | When you click the **Knit** button above a document will be generated that includes both content as well as the output of any embedded **R** code chunks within the document. You can embed an **R** code chunk like this (`cars` is a built-in **R** dataset): 49 | 50 | ```{r cars} 51 | summary(cars) 52 | ``` 53 | 54 | ## Inline code 55 | 56 | If you'd like to put the results of your analysis directly into your discussion, add inline code like this: 57 | 58 | > The `cos` of $2 \pi$ is `r cos(2*pi)`. 59 | 60 | Another example would be the direct calculation of the standard deviation: 61 | 62 | > The standard deviation of `speed` in `cars` is `r sd(cars$speed)`. 63 | 64 | One last neat feature is the use of the `ifelse` conditional statement which can be used to output text depending on the result of an **R** calculation: 65 | 66 | > `r ifelse(sd(cars$speed) < 6, "The standard deviation is less than 6.", "The standard deviation is equal to or greater than 6.")` 67 | 68 | Note the use of `>` here, which signifies a quotation environment that will be indented. 69 | 70 | As you see with `$2 \pi$` above, mathematics can be added by surrounding the mathematical text with dollar signs. More examples of this are in [Mathematics and Science] if you uncomment the code in [Math]. 71 | 72 | ## Including plots 73 | 74 | You can also embed plots. For example, here is a way to use the base **R** graphics package to produce a plot using the built-in `pressure` dataset: 75 | 76 | ```{r pressure, echo=FALSE, cache=TRUE} 77 | plot(pressure) 78 | ``` 79 | 80 | Note that the `echo=FALSE` parameter was added to the code chunk to prevent printing of the **R** code that generated the plot. There are plenty of other ways to add chunk options. More information is available at . 81 | 82 | Another useful chunk option is the setting of `cache=TRUE` as you see here. If document rendering becomes time consuming due to long computations or plots that are expensive to generate you can use knitr caching to improve performance. Later in this file, you'll see a way to reference plots created in **R** or external figures. 83 | 84 | ## Loading and exploring data 85 | 86 | Included in this template is a file called `flights.csv`. This file includes a subset of the larger dataset of information about all flights that departed from Seattle and Portland in 2014. More information about this dataset and its **R** package is available at . This subset includes only Portland flights and only rows that were complete with no missing values. Merges were also done with the `airports` and `airlines` data sets in the `pnwflights14` package to get more descriptive airport and airline names. 87 | 88 | We can load in this data set using the following command: 89 | 90 | ```{r load_data} 91 | flights <- read.csv("data/flights.csv") 92 | ``` 93 | 94 | The data is now stored in the data frame called `flights` in **R**. To get a better feel for the variables included in this dataset we can use a variety of functions. Here we can see the dimensions (rows by columns) and also the names of the columns. 95 | 96 | ```{r str} 97 | dim(flights) 98 | names(flights) 99 | ``` 100 | 101 | Another good idea is to take a look at the dataset in table form. With this dataset having more than 50,000 rows, we won't explicitly show the results of the command here. I recommend you enter the command into the Console **_after_** you have run the **R** chunks above to load the data into **R**. 102 | 103 | ```{r view_flights, eval=FALSE} 104 | View(flights) 105 | ``` 106 | 107 | While not required, it is highly recommended you use the `dplyr` package to manipulate and summarize your data set as needed. It uses a syntax that is easy to understand using chaining operations. Below I've created a few examples of using `dplyr` to get information about the Portland flights in 2014. You will also see the use of the `ggplot2` package, which produces beautiful, high-quality academic visuals. 108 | 109 | We begin by checking to ensure that needed packages are installed and then we load them into our current working environment: 110 | 111 | ```{r load_pkgs, message=FALSE} 112 | # List of packages required for this analysis 113 | pkg <- c("dplyr", "ggplot2", "knitr", "bookdown", "devtools") 114 | # Check if packages are not installed and assign the 115 | # names of the packages not installed to the variable new.pkg 116 | new.pkg <- pkg[!(pkg %in% installed.packages())] 117 | # If there are any packages in the list that aren't installed, 118 | # install them 119 | if (length(new.pkg)) 120 | install.packages(new.pkg, repos = "http://cran.rstudio.com") 121 | # Load packages (huskydown will load all of the packages as well) 122 | library(huskydown) 123 | ``` 124 | 125 | \clearpage 126 | 127 | The example we show here does the following: 128 | 129 | - Selects only the `carrier_name` and `arr_delay` from the `flights` dataset and then assigns this subset to a new variable called `flights2`. 130 | 131 | - Using `flights2`, we determine the largest arrival delay for each of the carriers. 132 | 133 | ```{r max_delays} 134 | flights2 <- flights %>% 135 | select(carrier_name, arr_delay) 136 | max_delays <- flights2 %>% 137 | group_by(carrier_name) %>% 138 | summarize(max_arr_delay = max(arr_delay, na.rm = TRUE)) 139 | ``` 140 | 141 | A useful function in the `knitr` package for making nice tables in _R Markdown_ is called `kable`. It is much easier to use than manually entering values into a table by copying and pasting values into Excel or LaTeX. This again goes to show how nice reproducible documents can be! (Note the use of `results="asis"`, which will produce the table instead of the code to create the table.) The `caption.short` argument is used to include a shorter title to appear in the List of Tables. 142 | 143 | ```{r maxdelays, results="asis"} 144 | kable(max_delays, 145 | col.names = c("Airline", "Max Arrival Delay"), 146 | caption = "Maximum Delays by Airline", 147 | caption.short = "Max Delays by Airline", 148 | longtable = TRUE, 149 | booktabs = TRUE) 150 | ``` 151 | 152 | The last two options make the table a little easier-to-read. 153 | 154 | We can further look into the properties of the largest value here for American Airlines Inc. To do so, we can isolate the row corresponding to the arrival delay of 1539 minutes for American in our original `flights` dataset. 155 | 156 | 157 | ```{r max_props} 158 | flights %>% filter(arr_delay == 1539, 159 | carrier_name == "American Airlines Inc.") %>% 160 | select(-c(month, day, carrier, dest_name, hour, 161 | minute, carrier_name, arr_delay)) 162 | ``` 163 | 164 | We see that the flight occurred on March 3rd and departed a little after 2 PM on its way to Dallas/Fort Worth. Lastly, we show how we can visualize the arrival delay of all departing flights from Portland on March 3rd against time of departure. 165 | 166 | ```{r march3plot, fig.height=3, fig.width=6} 167 | flights %>% filter(month == 3, day == 3) %>% 168 | ggplot(aes(x = dep_time, y = arr_delay)) + geom_point() 169 | ``` 170 | 171 | ## Additional resources 172 | 173 | - _Markdown_ Cheatsheet - 174 | 175 | - _R Markdown_ Reference Guide - 176 | 177 | - Introduction to `dplyr` - 178 | 179 | - `ggplot2` Documentation - 180 | -------------------------------------------------------------------------------- /R/infrastructure-git.R: -------------------------------------------------------------------------------- 1 | # unexported fns from devtools, we include them here so 2 | # we don't have to use ::: 3 | # from 4 | # https://raw.githubusercontent.com/hadley/devtools/6bb4b5f36cdfaee4d7e2f0a1f7f71ffeaf4aaf2f/R/infrastructure-git.R 5 | 6 | 7 | 8 | #' Initialise a git repository. 9 | #' 10 | #' @param message Message to use for first commit. 11 | #' @param pkg Path to package. See \code{\link{as.package}} for more 12 | #' information. 13 | #' @family git infrastructure 14 | #' @export 15 | #' @examples 16 | #' \dontrun{use_git()} 17 | use_git <- function(message = "Initial commit", pkg = ".") { 18 | use_git_with_config(message = message, pkg = pkg) 19 | } 20 | 21 | use_git_with_config <- function(message, pkg, add_user_config = FALSE, quiet = FALSE) { 22 | pkg <- as.package(pkg) 23 | 24 | if (uses_git(pkg$path)) { 25 | usethis:::done("Git is already initialized") 26 | return(invisible()) 27 | } 28 | 29 | if (!quiet) { 30 | usethis:::done("Initialising repo") 31 | } 32 | r <- git2r::init(pkg$path) 33 | 34 | if (add_user_config) { 35 | git2r::config(r, global = FALSE, user.name = "user", user.email = "user@email.xx") 36 | } 37 | 38 | use_git_ignore(c(".Rproj.user", ".Rhistory", ".RData"), pkg = pkg, quiet = quiet) 39 | 40 | if (!quiet) { 41 | usethis:::done("Adding files and committing") 42 | } 43 | paths <- unlist(git2r::status(r)) 44 | git2r::add(r, paths) 45 | git2r::commit(r, message) 46 | 47 | invisible() 48 | } 49 | 50 | #' Connect a local repo with GitHub. 51 | #' 52 | #' If the current repo does not use git, calls \code{\link{use_git}} 53 | #' automatically. \code{\link{use_github_links}} is called to populate the 54 | #' \code{URL} and \code{BugReports} fields of DESCRIPTION. 55 | #' 56 | #' @section Authentication: 57 | #' 58 | #' A new GitHub repo will be created via the GitHub API, therefore you must 59 | #' provide a GitHub personal access token (PAT) via the argument 60 | #' \code{auth_token}, which defaults to the value of the \code{GITHUB_PAT} 61 | #' environment variable. Obtain a PAT from 62 | #' \url{https://github.com/settings/tokens}. The "repo" scope is required 63 | #' which is one of the default scopes for a new PAT. 64 | #' 65 | #' The argument \code{protocol} reflects how you wish to authenticate with 66 | #' GitHub for this repo in the long run. For either \code{protocol}, a remote 67 | #' named "origin" is created, an initial push is made using the specified 68 | #' \code{protocol}, and a remote tracking branch is set. The URL of the 69 | #' "origin" remote has the form \code{git@@github.com:/.git} 70 | #' (\code{protocol = "ssh"}, the default) or 71 | #' \code{https://github.com//.git} (\code{protocol = 72 | #' "https"}). For \code{protocol = "ssh"}, it is assumed that public and 73 | #' private keys are in the default locations, \code{~/.ssh/id_rsa.pub} and 74 | #' \code{~/.ssh/id_rsa}, respectively, and that \code{ssh-agent} is configured 75 | #' to manage any associated passphrase. Alternatively, specify a 76 | #' \code{\link[git2r]{cred_ssh_key}} object via the \code{credentials} 77 | #' parameter. 78 | #' 79 | #' @inheritParams use_git 80 | #' @param auth_token Provide a personal access token (PAT) from 81 | #' \url{https://github.com/settings/tokens}. Defaults to the \code{GITHUB_PAT} 82 | #' environment variable. 83 | #' @param private If \code{TRUE}, creates a private repository. 84 | #' @param host GitHub API host to use. Override with the endpoint-root for your 85 | #' GitHub enterprise instance, for example, 86 | #' "https://github.hostname.com/api/v3". 87 | #' @param protocol transfer protocol, either "ssh" (the default) or "https" 88 | #' @param credentials A \code{\link[git2r]{cred_ssh_key}} specifying specific 89 | #' ssh credentials or NULL for default ssh key and ssh-agent behaviour. 90 | #' Default is NULL. 91 | #' @family git infrastructure 92 | #' @export 93 | #' @examples 94 | #' \dontrun{ 95 | #' ## to use default ssh protocol 96 | #' create("testpkg") 97 | #' use_github(pkg = "testpkg") 98 | #' 99 | #' ## or use https 100 | #' create("testpkg2") 101 | #' use_github(pkg = "testpkg2", protocol = "https") 102 | #' } 103 | use_github <- function(auth_token = github_pat(), private = FALSE, pkg = ".", 104 | host = "https://api.github.com", 105 | protocol = c("ssh", "https"), credentials = NULL) { 106 | 107 | if (is.null(auth_token)) { 108 | stop("GITHUB_PAT required to create new repo") 109 | } 110 | 111 | protocol <- match.arg(protocol) 112 | 113 | pkg <- as.package(pkg) 114 | use_git(pkg = pkg) 115 | 116 | if (uses_github(pkg$path)) { 117 | usethis:::done("GitHub is already initialized") 118 | return(invisible()) 119 | } 120 | 121 | usethis:::done("Checking title and description") 122 | usethis:::done(" Title: ", pkg$title) 123 | usethis:::done(" Description: ", pkg$description) 124 | if (interactive() && !yesno("Are title and description ok?")) { 125 | TRUE 126 | } else { 127 | FALSE 128 | } 129 | 130 | 131 | message("* Creating GitHub repository") 132 | create <- 133 | github_POST( 134 | "user/repos", 135 | pat = auth_token, 136 | body = list( 137 | name = jsonlite::unbox(pkg$package), 138 | description = jsonlite::unbox(gsub("\n", " ", pkg$title)), 139 | private = jsonlite::unbox(private) 140 | ), 141 | host = host 142 | ) 143 | 144 | usethis:::done("Adding GitHub remote") 145 | r <- git2r::repository(pkg$path) 146 | origin_url <- switch(protocol, https = create$clone_url, ssh = create$ssh_url) 147 | git2r::remote_add(r, "origin", origin_url) 148 | 149 | usethis:::done("Adding GitHub links to DESCRIPTION") 150 | use_github_links(pkg$path, auth_token = auth_token, host = host) 151 | if (git_uncommitted(pkg$path)) { 152 | git2r::add(r, "DESCRIPTION") 153 | git2r::commit(r, "Add GitHub links to DESCRIPTION") 154 | } 155 | 156 | message("* Pushing to GitHub and setting remote tracking branch") 157 | if (protocol == "ssh") { 158 | ## [1] push via ssh required for success setting remote tracking branch 159 | ## [2] to get passphrase from ssh-agent, you must use NULL credentials 160 | git2r::push(r, "origin", "refs/heads/master", credentials = credentials) 161 | } else { ## protocol == "https" 162 | ## in https case, when GITHUB_PAT is passed as password, 163 | ## the username is immaterial, but git2r doesn't know that 164 | cred <- git2r::cred_user_pass("EMAIL", auth_token) 165 | git2r::push(r, "origin", "refs/heads/master", credentials = cred) 166 | } 167 | git2r::branch_set_upstream(git2r::head(r), "origin/master") 168 | 169 | usethis:::done("View repo at ", create$html_url) 170 | 171 | invisible(NULL) 172 | } 173 | 174 | 175 | #' Add a git hook. 176 | #' 177 | #' @param hook Hook name. One of "pre-commit", "prepare-commit-msg", 178 | #' "commit-msg", "post-commit", "applypatch-msg", "pre-applypatch", 179 | #' "post-applypatch", "pre-rebase", "post-rewrite", "post-checkout", 180 | #' "post-merge", "pre-push", "pre-auto-gc". 181 | #' @param script Text of script to run 182 | #' @inheritParams use_git 183 | #' @export 184 | #' @family git infrastructure 185 | #' @keywords internal 186 | use_git_hook <- function(hook, script, pkg = ".") { 187 | pkg <- as.package(pkg) 188 | 189 | git_dir <- file.path(pkg$path, ".git") 190 | if (!file.exists(git_dir)) { 191 | stop("This project doesn't use git", call. = FALSE) 192 | } 193 | 194 | hook_dir <- file.path(git_dir, "hooks") 195 | if (!file.exists(hook_dir)) { 196 | dir.create(hook_dir) 197 | } 198 | 199 | hook_path <- file.path(hook_dir, hook) 200 | writeLines(script, hook_path) 201 | Sys.chmod(hook_path, "0744") 202 | } 203 | 204 | 205 | use_git_ignore <- function(ignores, directory = ".", pkg = ".", quiet = FALSE) { 206 | pkg <- as.package(pkg) 207 | 208 | paths <- paste0("`", ignores, "`", collapse = ", ") 209 | if (!quiet) { 210 | usethis:::done("Adding ", paths, " to ", file.path(directory, ".gitignore")) 211 | } 212 | 213 | path <- file.path(pkg$path, directory, ".gitignore") 214 | union_write(path, ignores) 215 | 216 | invisible(TRUE) 217 | } 218 | 219 | #' Add GitHub links to DESCRIPTION. 220 | #' 221 | #' Populates the URL and BugReports fields of DESCRIPTION with 222 | #' \code{https://github.com//} AND 223 | #' \code{https://github.com///issues}, respectively, unless 224 | #' those fields already exist. 225 | #' 226 | #' @inheritParams use_git 227 | #' @param auth_token Provide a personal access token (PAT) from 228 | #' \url{https://github.com/settings/tokens}. Defaults to the \code{GITHUB_PAT} 229 | #' environment variable. 230 | #' @param host GitHub API host to use. Override with the endpoint-root for your 231 | #' GitHub enterprise instance, for example, 232 | #' "https://github.hostname.com/api/v3". 233 | #' @family git infrastructure 234 | #' @keywords internal 235 | #' @export 236 | use_github_links <- function(pkg = ".", auth_token = github_pat(), 237 | host = "https://api.github.com") { 238 | 239 | if (!uses_github(pkg)) { 240 | stop("Cannot detect that package already uses GitHub.\n", 241 | "You might want to run use_github().") 242 | } 243 | 244 | gh_info <- github_info(pkg) 245 | pkg <- as.package(pkg) 246 | 247 | desc_path <- file.path(pkg$path, "DESCRIPTION") 248 | desc <- new_desc <- read_dcf(desc_path) 249 | 250 | path_to_repo <- paste("repos", gh_info$fullname, sep = "/") 251 | res <- github_GET(path = path_to_repo, pat = auth_token, host = host) 252 | github_URL <- res$html_url 253 | 254 | fill <- function(d, f, filler) { 255 | if (is.null(d[[f]]) || identical(d[[f]], "")) { 256 | d[[f]] <- filler 257 | } else { 258 | message("Existing ", f, " field found and preserved") 259 | } 260 | d 261 | } 262 | new_desc <- fill(new_desc, "URL", github_URL) 263 | new_desc <- fill(new_desc, "BugReports", file.path(github_URL, "issues")) 264 | 265 | if (!identical(desc, new_desc)) 266 | write_dcf(desc_path, new_desc) 267 | 268 | new_desc[c("URL", "BugReports")] 269 | } 270 | -------------------------------------------------------------------------------- /inst/templates/thesis_template/03-chap3.Rmd: -------------------------------------------------------------------------------- 1 | ```{r include_packages_2, include = FALSE} 2 | # This chunk ensures that the huskydown package is 3 | # installed and loaded. This huskydown package includes 4 | # the template files for the thesis and also two functions 5 | # used for labeling and referencing 6 | if(!require(devtools)) 7 | install.packages("devtools", repos = "http://cran.rstudio.com") 8 | if(!require(dplyr)) 9 | install.packages("dplyr", repos = "http://cran.rstudio.com") 10 | if(!require(ggplot2)) 11 | install.packages("ggplot2", repos = "http://cran.rstudio.com") 12 | if(!require(ggplot2)) 13 | install.packages("bookdown", repos = "http://cran.rstudio.com") 14 | if(!require(huskydown)){ 15 | library(devtools) 16 | devtools::install_github("benmarwick/huskydown") 17 | } 18 | library(huskydown) 19 | flights <- read.csv("data/flights.csv") 20 | ``` 21 | 22 | 23 | # Tables, Graphics, References, and Labels {#ref-labels} 24 | 25 | ## Tables 26 | 27 | By far the easiest way to present tables in your thesis is to store the contents of the table in a CSV or Excel file, then read that file in to your R Markdown document as a data frame. Then you can style the table with the `kable` function, or functions in the [kableExtra](https://cran.r-project.org/web/packages/kableExtra/index.html) pacakge. 28 | 29 | In addition to the tables that can be automatically generated from a data frame in **R** that you saw in [R Markdown Basics] using the `kable` function, you can also create tables using _pandoc_. (More information is available at .) This might be useful if you don't have values specifically stored in **R**, but you'd like to display them in table form. Below is an example. Pay careful attention to the alignment in the table and hyphens to create the rows and columns. Generally I don't recommend this approach of typing the table directly into your R Markdown document. 30 | 31 | ---------------------------------------------------------------------------------- 32 | Factors Correlation between Parents & Child Inherited 33 | ------------------------- ----------------------------------------- -------------- 34 | Education -0.49 Yes 35 | 36 | Socio-Economic Status 0.28 Slight 37 | 38 | Income 0.08 No 39 | 40 | Family Size 0.18 Slight 41 | 42 | Occupational Prestige 0.21 Slight 43 | ------------------------- ----------------------------------------- -------------- 44 | Table: (\#tab:inher) Correlation of Inheritance Factors for Parents and Child 45 | 46 | We can also create a link to the table by doing the following: Table \@ref(tab:inher). If you go back to [Loading and exploring data] and look at the `kable` table, we can create a reference to this max delays table too: Table \@ref(tab:maxdelays). The addition of the `(\#tab:inher)` option to the end of the table caption allows us to then make a reference to Table `\@ref(tab:label)`. Note that this reference could appear anywhere throughout the document after the table has appeared. 47 | 48 | 49 | 50 | \clearpage 51 | 52 | 54 | 55 | 56 | ## Figures 57 | 58 | If your thesis has a lot of figures, _R Markdown_ might behave better for you than that other word processor. One perk is that it will automatically number the figures accordingly in each chapter. You'll also be able to create a label for each figure, add a caption, and then reference the figure in a way similar to what we saw with tables earlier. If you label your figures, you can move the figures around and _R Markdown_ will automatically adjust the numbering for you. No need for you to remember! So that you don't have to get too far into LaTeX to do this, a couple **R** functions have been created for you to assist. You'll see their use below. 59 | 60 | 65 | 66 | 67 | In the **R** chunk below, we will load in a picture stored as `uw.png` in our main directory. We then give it the caption of "UW logo", the label of "uwlogo", and specify that this is a figure. Make note of the different **R** chunk options that are given in the R Markdown file (not shown in the knitted document). 68 | 69 | ```{r uwlogo, fig.cap="UW logo"} 70 | include_graphics(path = "figure/uw.png") 71 | ``` 72 | 73 | Here is a reference to the UW logo: Figure \@ref(fig:uwlogo). Note the use of the `fig:` code here. By naming the **R** chunk that contains the figure, we can then reference that figure later as done in the first sentence here. We can also specify the caption for the figure via the R chunk option `fig.cap`. 74 | 75 | \clearpage 76 | 77 | 78 | 79 | Below we will investigate how to save the output of an **R** plot and label it in a way similar to that done above. Recall the `flights` dataset from Chapter \@ref(rmd-basics). (Note that we've shown a different way to reference a section or chapter here.) We will next explore a bar graph with the mean flight departure delays by airline from Portland for 2014. Note also the use of the `scale` parameter which is discussed on the next page. 80 | 81 | ```{r delaysboxplot, warnings=FALSE, messages=FALSE, fig.cap="Mean Delays by Airline", fig.width=6} 82 | flights %>% group_by(carrier) %>% 83 | summarize(mean_dep_delay = mean(dep_delay)) %>% 84 | ggplot(aes(x = carrier, y = mean_dep_delay)) + 85 | geom_bar(position = "identity", stat = "identity", fill = "red") 86 | ``` 87 | 88 | Here is a reference to this image: Figure \@ref(fig:delaysboxplot). 89 | 90 | A table linking these carrier codes to airline names is available at . 91 | 92 | \clearpage 93 | 94 | Next, we will explore the use of the `out.extra` chunk option, which can be used to shrink or expand an image loaded from a file by specifying `"scale= "`. Here we use the mathematical graph stored in the "subdivision.pdf" file. 95 | 96 | ```{r subd, results="asis", echo=FALSE, fig.cap="Subdiv. graph", out.extra="scale=0.75"} 97 | include_graphics("figure/subdivision.pdf") 98 | ``` 99 | 100 | Here is a reference to this image: Figure \@ref(fig:subd). Note that `echo=FALSE` is specified so that the **R** code is hidden in the document. 101 | 102 | **More Figure Stuff** 103 | 104 | Lastly, we will explore how to rotate and enlarge figures using the `out.extra` chunk option. (Currently this only works in the PDF version of the book.) 105 | 106 | ```{r subd2, results="asis", echo=FALSE, out.extra="angle=180, scale=1.1", fig.cap="A Larger Figure, Flipped Upside Down"} 107 | include_graphics("figure/subdivision.pdf") 108 | ``` 109 | 110 | As another example, here is a reference: Figure \@ref(fig:subd2). 111 | 112 | ## Footnotes and Endnotes 113 | 114 | You might want to footnote something. ^[footnote text] The footnote will be in a smaller font and placed appropriately. Endnotes work in much the same way. 115 | 116 | ## Bibliographies 117 | 118 | Of course you will need to cite things, and you will probably accumulate an armful of sources. There are a variety of tools available for creating a bibliography database (stored with the .bib extension). In addition to BibTeX suggested below, you may want to consider using the free and easy-to-use tool called Zotero. Some Zotero documentation is at . In addition, a tutorial is available from Middlebury College at . 119 | 120 | _R Markdown_ uses _pandoc_ () to build its bibliographies. One nice caveat of this is that you won't have to do a second compile to load in references as standard LaTeX requires. To cite references in your thesis (after creating your bibliography database), place the reference name inside square brackets and precede it by the "at" symbol. For example, here's a reference to a book about worrying: [@Molina1994]. This `Molina1994` entry appears in a file called `thesis.bib` in the `bib` folder. This bibliography database file was created by a program called BibTeX. You can call this file something else if you like (look at the YAML header in the main .Rmd file) and, by default, is to placed in the `bib` folder. 121 | 122 | For more information about BibTeX and bibliographies, see ()^[@reedweb2007]. There are three pages on this topic: _bibtex_ (which talks about using BibTeX, at ), _bibtexstyles_ (about how to find and use the bibliography style that best suits your needs, at ) and _bibman_ (which covers how to make and maintain a bibliography by hand, without BibTeX, at ). The last page will not be useful unless you have only a few sources. 123 | 124 | If you look at the YAML header at the top of the main .Rmd file you can see that we can specify the style of the bibliography by referencing the appropriate csl file. You can download a variety of different style files at . Make sure to download the file into the csl folder. 125 | 126 | **Tips for Bibliographies** 127 | 128 | - Like with thesis formatting, the sooner you start compiling your bibliography for something as large as thesis, the better. 129 | - The cite key (a citation's label) needs to be unique from the other entries. 130 | - When you have more than one author or editor, you need to separate each author's name by the word "and" e.g. `Author = {Noble, Sam and Youngberg, Jessica},`. 131 | - Bibliographies made using BibTeX (whether manually or using a manager) accept LaTeX markup, so you can italicize and add symbols as necessary. 132 | - To force capitalization in an article title or where all lowercase is generally used, bracket the capital letter in curly braces. 133 | 134 | ## Anything else? 135 | 136 | If you'd like to see examples of other things in this template, please [contact us](https://github.com/benmarwick/huskydown/issues/new) (email ) with your suggestions. We love to see people using _R Markdown_ for their theses, and are happy to help. 137 | 138 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, echo = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "README-" 12 | ) 13 | ``` 14 | 15 | # rrtools: Tools for Writing Reproducible Research in R 16 | 17 | [![Travis-CI Build Status](https://travis-ci.org/benmarwick/rrtools.svg?branch=master)](https://travis-ci.org/benmarwick/rrtools) [![Circle-CI Build Status](https://circleci.com/gh/benmarwick/rrtools.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/benmarwick/rrtools) 18 | 19 | ## Motivation 20 | 21 | The goal of **rrtools** is to provide instructions, templates, and functions for making a basic compendium suitable for writing reproducible research with [R](https://www.r-project.org). This package documents the key steps and provides convenient functions for quickly creating a new research compendium. The approach is based generally on [Kitzes et al. (2017)](https://www.practicereproducibleresearch.org), and more specifically on [Marwick (2017)](https://doi.org/10.1007/s10816-015-9272-9), [Marwick et al. (2017)](https://doi.org/10.7287/peerj.preprints.3192v1), and [Wickham's (2017)](https://docs.google.com/document/d/1LzZKS44y4OEJa4Azg5reGToNAZL0e0HSUwxamNY7E-Y/edit#) work using the R package structure as the basis for a research compendium. 22 | 23 | rrtools provides a template for doing scholarly writing in a literate programming environment using [R Markdown](http://rmarkdown.rstudio.com) and [bookdown](https://bookdown.org/home/about.html). It also allows for isolation of your computational environment using [Docker](https://www.docker.com/what-docker), package versioning using [MRAN](https://mran.microsoft.com/documents/rro/reproducibility/), and continuous integration using [Travis](https://docs.travis-ci.com/user/for-beginners). It makes a convenient starting point for writing a journal article, report, or thesis. 24 | 25 | The functions in rrtools allow you to use R to easily follow the best practices outlined in several major scholarly publications on reproducible research. In addition to those cited above, [Wilson et al. (2017)](https://doi.org/10.1371/journal.pcbi.1005510), [Piccolo & Frampton (2016)](https://gigascience.biomedcentral.com/articles/10.1186/s13742-016-0135-4), [Stodden & Miguez (2014)](http://doi.org/10.5334/jors.ay) and rOpenSci (2017[a](http://ropensci.github.io/reproducibility-guide/), [b](https://github.com/ropensci/rrrpkg)) are important sources that have influenced our approach to this package. 26 | 27 | ## Installation 28 | 29 | You can install rrtools from GitHub with: 30 | 31 | ```{r gh-installation, eval = FALSE} 32 | # install.packages("devtools") 33 | devtools::install_github("benmarwick/rrtools") 34 | ``` 35 | 36 | ## How to use 37 | 38 | ### Quick start 39 | 40 | To make a quick start on creating a compendium, use the `create_compendium()` function. This function will create a compendium that is instantly ready to work with: 41 | 42 | ```{r eval = FALSE} 43 | library(rrtools) # will confirm that you have Git installed and configured 44 | create_compendium("pkgname") 45 | ``` 46 | 47 | This function combines the key parts of the first five steps described below, using sensible, widely-used defaults. It gives detailed console output to guide you on the next steps to take with your compendium (it will not create a GitHub repository, or do the Travis and Docker steps detailed below). 48 | 49 | ### Detailed step-by-step creation of a research compendium 50 | 51 | To create a reproducible research compendium step-by-step using the rrtools approach, follow these detailed instructions. We use [RStudio](https://www.rstudio.com/products/rstudio/#Desktop), and recommend it, but is not required for these steps to work. We recommend copy-pasting these directly into your console, and editing the options before running. We don't recommend saving these lines in a script in your project: they are meant to be once-off setup functions. 52 | 53 | #### 1. `rrtools::use_compendium("pkgname")` 54 | 55 | - this uses `usethis::create_package()` to create a basic R package with the name `pkgname` (you should use a different one), and then, if you're using RStudio, opens the project. If you're not using RStudio, it sets the working directory to the `pkgname` directory. 56 | - we need to: 57 | + choose a location for the compendium package. We recommend two ways to do this. First, you can specify the full path directly, (e.g., `rrtools::use_compendium("C:/Users/bmarwick/Desktop/pkgname")`). Alternatively, you can set the working directory in RStudio using the drop-down menu: `Session` -> `Set Working Directory` and then run `rrtools::use_compendium("pkgname")`. 58 | + edit the `DESCRIPTION` file (located in your `pkgname` directory) to include accurate metadata 59 | + periodically update the `Imports:` section of the `DESCRIPTION` file with the names of packages used in the code we write in the Rmd document(s) (e.g., `usethis::use_package("dplyr", "imports")`) 60 | 61 | #### 2. `usethis::use_mit_license(name = "My Name")` 62 | 63 | - this adds a reference to the MIT license in the [DESCRIPTION](DESCRIPTION) file and generates a [LICENSE](LICENSE) file listing the name provided as the copyright holder 64 | - to use a different license, replace this line with `usethis::use_gpl3_license(name = "My Name")`, or follow the instructions for other licenses 65 | 66 | #### 3. `usethis::use_git()` then `usethis::use_github(auth_token = "xxxx", protocol = "https", private = FALSE)` 67 | 68 | - if you are connected to the internet, this initializes a local git repository (`use_git()`), then `use_github()` connects to [GitHub](https://github.com), and creates a remote repository 69 | - if you are not connected to the internet, use `use_git()` to initialise a local git repository for your project, and save the `use_github` step for when you are online. Reopen your project in RStudio to see the git buttons on the toolbar. 70 | - we need to: 71 | + install and configure git _before_ running this line. See [Happy Git With R](http://happygitwithr.com) for details on how to do this. 72 | + get a [personal access token](https://github.com/settings/tokens), and replace "xxxx" with that token. When you do so (click "Generate new token"), make sure the "repo" scope is included by checking the "repo" box. Don't save this token in your project, keep it elsewhere. 73 | + solve any errors that might occur during this step by using the development version of the git2r package, which can be installed with `devtools::install_github("ropensci/git2r")` 74 | 75 | #### 4. `rrtools::use_readme_rmd()` 76 | 77 | - this generates [README.Rmd](README.Rmd) and renders it to [README.md](README.md), ready to display on GitHub. It contains: 78 | + a template citation to show others how to cite your project. Edit this to include the correct title and [DOI](https://doi.org). 79 | + license information for the text, figures, code and data in your compendium 80 | - this also adds two other markdown files: a code of conduct for users [CONDUCT.md](CONDUCT.md), and basic instructions for people who want to contribute to your project [CONTRIBUTING.md](CONTRIBUTING.md), including for first-timers to git and GitHub. 81 | - render this document after each change to refresh [README.md](README.md), which is the file that GitHub displays on the repository home page 82 | 83 | #### 5. `rrtools::use_analysis()` 84 | 85 | - this function has three `location = ` options: `top_level` to create a top-level `analysis/` directory, `inst` to create an `inst/` directory (so that all the sub-directories are available after the package is installed), and `vignettes` to create a `vignettes/` directory (and automatically update the `DESCRIPTION`). The default is a top-level `analysis/`. 86 | - for each option, the contents of the sub-directories are the same, with the following (using the default `analysis/` for example): 87 | 88 | ``` 89 | analysis/ 90 | | 91 | ├── paper/ 92 | │ ├── paper.Rmd # this is the main document to edit 93 | │ └── references.bib # this contains the reference list information 94 | 95 | ├── figures/ # location of the figures produced by the Rmd 96 | | 97 | ├── data/ 98 | │ ├── raw_data/ # data obtained from elsewhere 99 | │ └── derived_data/ # data generated during the analysis 100 | | 101 | └── templates 102 | ├── journal-of-archaeological-science.csl 103 | | # this sets the style of citations & reference list 104 | ├── template.docx # used to style the output of the paper.Rmd 105 | └── template.Rmd 106 | ``` 107 | 108 | - the `paper.Rmd` is ready to write in and render with bookdown. It includes: 109 | + a YAML header that identifies the `references.bib` file and the supplied `csl` file (to style the reference list) 110 | + a colophon that adds some git commit details to the end of the document. This means that the output file (HTML/PDF/Word) is always traceable to a specific state of the code. 111 | - the `references.bib` file has just one item to demonstrate the format. It is ready to insert more reference details. 112 | - you can replace the supplied `csl` file with a different citation style from 113 | - we recommend using the [citr addin](https://github.com/crsh/citr) and [Zotero](https://www.zotero.org/) to efficiently insert citations while writing in an Rmd file 114 | - remember that the `Imports:` field in the `DESCRIPTION` file must include the names of all packages used in analysis documents (e.g. `paper.Rmd`). We have a helper function `rrtools::add_dependencies_to_description()` that will scan the Rmd file, identify libraries used in there, and add them to the `DESCRIPTION` file. 115 | - this function has an `data_in_git =` argument, which is `TRUE` by default. If set to `FALSE` you will exclude files in the `data/` directory from being tracked by git and prevent them from appearing on GitHub. You should set `data_in_git = FALSE` if your data files are large (>100 mb is the limit for GitHub) or you do not want to make the data files publicly accessible on GitHub. 116 | - if you're writing a PhD thesis, replace `rrtools::use_analysis()` with `rmarkdown::draft('index.Rmd', template = 'thesis', package = 'huskydown', create_dir = TRUE)` to create a thesis template from the [huskydown package](https://github.com/benmarwick/huskydown) 117 | - To load your custom code in the `paper.Rmd`, you have a few options. You can write all your R code in chunks in the Rmd, that's the simplest method. Or you can write R code in script files in `/R`, and include `devtools::load_all(".")` at the top of your `paper.Rmd`. Or you can write functions in `/R` and use `library(pkgname)` at the top of your `paper.Rmd`, or omit `library` and preface each function call with `pkgname::`. Up to you to choose whatever seems most natural to you. 118 | 119 | #### 6. `rrtools::use_dockerfile()` 120 | 121 | - this creates a basic Dockerfile using [`rocker/verse`](https://github.com/rocker-org/rocker) as the base image 122 | - the version of R in your rocker container will match the version used when you run this function (e.g., `rocker/verse:3.5.0`) 123 | - [`rocker/verse`](https://github.com/rocker-org/rocker) includes R, the [tidyverse](http://tidyverse.org/), RStudio, pandoc and LaTeX, so compendium build times are very fast on travis 124 | - we need to: 125 | + edit the Dockerfile to add linux dependencies (for R packages that require additional libraries outside of R). You can find out what these are by browsing the [DESCRIPTION](DESCRIPTION) files of the other packages you're using, and looking in the SystemRequirements field for each package. If you are getting build errors on travis, check the logs. Often, the error messages will include the names of missing libraries. 126 | + modify which Rmd files are rendered when the container is made 127 | + have a public GitHub repo to use the Dockerfile that this function generates. It is possible to keep the repository private and run a local Docker container with minor modifications to the Dockerfile that this function generates. Or we can use `rrtools::use_circleci()` to build our Docker container privately at , from a private GitHub repo. 128 | - If we want to use Travis on our project, we need to make an account at to receive our Docker container after a successful build on travis 129 | 130 | #### 7. `rrtools::use_travis()` 131 | 132 | - this creates a minimal `.travis.yml` file. By default it configures travis to build our Docker container from our Dockerfile, and build, install and run our custom package in this container. By specifying `docker = FALSE` in this function, the travis file will not use Docker in travis, but run R directly on the travis infrastructure. We recommend using Docker because it offers greater computational isolation and saves a substantial amount of time during the travis build because the base image contains many pre-compiled packages. 133 | - we need to: 134 | + go to to connect to our repo 135 | + add environment variables to enable push of the Docker container to the Docker Hub 136 | + make an account at to host our Docker container 137 | - Note that you should run this function only when we are ready for our GitHub repository to be public. The free travis service we're using here requires your GitHub repository to be public. It will not work on private repositories. If you want to keep your GitHub repo private until after publication, you can use `rrtools::use_circleci()` for running free private continuous integration tests at , instead of travis. With `rrtools::use_circleci(docker_hub = FALSE)` we can stop our Docker container from appearing on Docker Hub, so our Docker container stays completely private. 138 | 139 | #### 8. `usethis::use_testthat()` 140 | 141 | - if you add functions in `R/`, include tests to ensure they function as intended 142 | - create tests.R in `tests/testthat/` and check for template 143 | 144 | You should be able to follow these steps to get a new research compendium repository connected to travis and ready to write in just a few minutes. 145 | 146 | ## References 147 | 148 | Kitzes, J., Turek, D., & Deniz, F. (Eds.). (2017). _The Practice of Reproducible Research: Case Studies and Lessons from the Data-Intensive Sciences_. Oakland, CA: University of California Press. 149 | 150 | Marwick, B. (2017). Computational reproducibility in archaeological research: Basic principles and a case study of their implementation. _Journal of Archaeological Method and Theory_, 24(2), 424-450. 151 | 152 | Marwick, B., Boettiger, C. & L. Mullen (2017). Packaging data analytical work reproducibly using R (and friends). _PeerJ Preprints_ 5:e3192v1 153 | 154 | Piccolo, S. R. and M. B. Frampton (2016). "Tools and techniques for computational reproducibility." GigaScience 5(1): 30. 155 | 156 | rOpenSci community (2017a). Reproducibility in Science A Guide to enhancing reproducibility in scientific results and writing. Online at 157 | 158 | rOpenSci community (2017b). rrrpkg: Use of an R package to facilitate reproducible research. Online at 159 | 160 | Stodden, V. & Miguez, S., (2014). Best Practices for Computational Science: Software Infrastructure and Environments for Reproducible and Extensible Research. Journal of Open Research Software. 2(1), p.e21. DOI: 161 | 162 | Wickham, H. (2017) _Research compendia_. Note prepared for the 2017 rOpenSci Unconf. 163 | 164 | Wilson G, Bryan J, Cranston K, Kitzes J, Nederbragt L, et al. (2017). Good enough practices in scientific computing. _PLOS Computational Biology_ 13(6): e1005510. 165 | 166 | ## Contributing 167 | 168 | If you would like to contribute to this project, please start by reading our [Guide to Contributing](CONTRIBUTING.md). Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. 169 | 170 | ## Acknowledgements 171 | 172 | This project was developed during the 2017 Summer School on Reproducible Research in Landscape Archaeology at the Freie Universität Berlin (17-21 July), funded and jointly organized by [Exc264 Topoi](https://www.topoi.org/), [CRC1266](http://www.sfb1266.uni-kiel.de/en), and [ISAAKiel](https://isaakiel.github.io/). Special thanks to [Sophie C. Schmidt](https://github.com/SCSchmidt) for help. The convenience functions in this package are inspired by similar functions in the [`usethis`](https://github.com/r-lib/usethis) package. 173 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # rrtools: Tools for Writing Reproducible Research in R 5 | 6 | [![Travis-CI Build 7 | Status](https://travis-ci.org/benmarwick/rrtools.svg?branch=master)](https://travis-ci.org/benmarwick/rrtools) 8 | [![Circle-CI Build 9 | Status](https://circleci.com/gh/benmarwick/rrtools.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/benmarwick/rrtools) 10 | 11 | ## Motivation 12 | 13 | The goal of **rrtools** is to provide instructions, templates, and 14 | functions for making a basic compendium suitable for writing 15 | reproducible research with [R](https://www.r-project.org). This package 16 | documents the key steps and provides convenient functions for quickly 17 | creating a new research compendium. The approach is based generally on 18 | [Kitzes et al. (2017)](https://www.practicereproducibleresearch.org), 19 | and more specifically on [Marwick 20 | (2017)](https://doi.org/10.1007/s10816-015-9272-9), [Marwick et al. 21 | (2017)](https://doi.org/10.7287/peerj.preprints.3192v1), and [Wickham’s 22 | (2017)](https://docs.google.com/document/d/1LzZKS44y4OEJa4Azg5reGToNAZL0e0HSUwxamNY7E-Y/edit#) 23 | work using the R package structure as the basis for a research 24 | compendium. 25 | 26 | rrtools provides a template for doing scholarly writing in a literate 27 | programming environment using [R Markdown](http://rmarkdown.rstudio.com) 28 | and [bookdown](https://bookdown.org/home/about.html). It also allows for 29 | isolation of your computational environment using 30 | [Docker](https://www.docker.com/what-docker), package versioning using 31 | [MRAN](https://mran.microsoft.com/documents/rro/reproducibility/), and 32 | continuous integration using 33 | [Travis](https://docs.travis-ci.com/user/for-beginners). It makes a 34 | convenient starting point for writing a journal article, report, or 35 | thesis. 36 | 37 | The functions in rrtools allow you to use R to easily follow the best 38 | practices outlined in several major scholarly publications on 39 | reproducible research. In addition to those cited above, [Wilson et al. 40 | (2017)](https://doi.org/10.1371/journal.pcbi.1005510), [Piccolo & 41 | Frampton 42 | (2016)](https://gigascience.biomedcentral.com/articles/10.1186/s13742-016-0135-4), 43 | [Stodden & Miguez (2014)](http://doi.org/10.5334/jors.ay) and rOpenSci 44 | (2017[a](http://ropensci.github.io/reproducibility-guide/), 45 | [b](https://github.com/ropensci/rrrpkg)) are important sources that have 46 | influenced our approach to this package. 47 | 48 | ## Installation 49 | 50 | You can install rrtools from GitHub with: 51 | 52 | ``` r 53 | # install.packages("devtools") 54 | devtools::install_github("benmarwick/rrtools") 55 | ``` 56 | 57 | ## How to use 58 | 59 | ### Quick start 60 | 61 | To make a quick start on creating a compendium, use the 62 | `create_compendium()` function. This function will create a compendium 63 | that is instantly ready to work 64 | with: 65 | 66 | ``` r 67 | library(rrtools) # will confirm that you have Git installed and configured 68 | create_compendium("pkgname") 69 | ``` 70 | 71 | This function combines the key parts of the first five steps described 72 | below, using sensible, widely-used defaults. It gives detailed console 73 | output to guide you on the next steps to take with your compendium (it 74 | will not create a GitHub repository, or do the Travis and Docker steps 75 | detailed below). 76 | 77 | ### Detailed step-by-step creation of a research compendium 78 | 79 | To create a reproducible research compendium step-by-step using the 80 | rrtools approach, follow these detailed instructions. We use 81 | [RStudio](https://www.rstudio.com/products/rstudio/#Desktop), and 82 | recommend it, but is not required for these steps to work. We recommend 83 | copy-pasting these directly into your console, and editing the options 84 | before running. We don’t recommend saving these lines in a script in 85 | your project: they are meant to be once-off setup functions. 86 | 87 | #### 1\. `rrtools::use_compendium("pkgname")` 88 | 89 | - this uses `usethis::create_package()` to create a basic R package 90 | with the name `pkgname` (you should use a different one), and then, 91 | if you’re using RStudio, opens the project. If you’re not using 92 | RStudio, it sets the working directory to the `pkgname` directory. 93 | - we need to: 94 | - choose a location for the compendium package. We recommend two 95 | ways to do this. First, you can specify the full path directly, 96 | (e.g., 97 | `rrtools::use_compendium("C:/Users/bmarwick/Desktop/pkgname")`). 98 | Alternatively, you can set the working directory in RStudio 99 | using the drop-down menu: `Session` -\> `Set Working Directory` 100 | and then run `rrtools::use_compendium("pkgname")`. 101 | - edit the `DESCRIPTION` file (located in your `pkgname` 102 | directory) to include accurate metadata 103 | - periodically update the `Imports:` section of the `DESCRIPTION` 104 | file with the names of packages used in the code we write in the 105 | Rmd document(s) (e.g., `usethis::use_package("dplyr", 106 | "imports")`) 107 | 108 | #### 2\. `usethis::use_mit_license(name = "My Name")` 109 | 110 | - this adds a reference to the MIT license in the 111 | [DESCRIPTION](DESCRIPTION) file and generates a [LICENSE](LICENSE) 112 | file listing the name provided as the copyright holder 113 | - to use a different license, replace this line with 114 | `usethis::use_gpl3_license(name = "My Name")`, or follow the 115 | instructions for other 116 | licenses 117 | 118 | #### 3\. `usethis::use_git()` then `usethis::use_github(auth_token = "xxxx", protocol = "https", private = FALSE)` 119 | 120 | - if you are connected to the internet, this initializes a local git 121 | repository (`use_git()`), then `use_github()` connects to 122 | [GitHub](https://github.com), and creates a remote repository 123 | - if you are not connected to the internet, use `use_git()` to 124 | initialise a local git repository for your project, and save the 125 | `use_github` step for when you are online. Reopen your project in 126 | RStudio to see the git buttons on the toolbar. 127 | - we need to: 128 | - install and configure git *before* running this line. See [Happy 129 | Git With R](http://happygitwithr.com) for details on how to do 130 | this. 131 | - get a [personal access 132 | token](https://github.com/settings/tokens), and replace “xxxx” 133 | with that token. When you do so (click “Generate new token”), 134 | make sure the “repo” scope is included by checking the “repo” 135 | box. Don’t save this token in your project, keep it elsewhere. 136 | - solve any errors that might occur during this step by using the 137 | development version of the git2r package, which can be installed 138 | with `devtools::install_github("ropensci/git2r")` 139 | 140 | #### 4\. `rrtools::use_readme_rmd()` 141 | 142 | - this generates [README.Rmd](README.Rmd) and renders it to 143 | [README.md](README.md), ready to display on GitHub. It contains: 144 | - a template citation to show others how to cite your project. 145 | Edit this to include the correct title and 146 | [DOI](https://doi.org). 147 | - license information for the text, figures, code and data in your 148 | compendium 149 | - this also adds two other markdown files: a code of conduct for users 150 | [CONDUCT.md](CONDUCT.md), and basic instructions for people who want 151 | to contribute to your project [CONTRIBUTING.md](CONTRIBUTING.md), 152 | including for first-timers to git and GitHub. 153 | - render this document after each change to refresh 154 | [README.md](README.md), which is the file that GitHub displays on 155 | the repository home page 156 | 157 | #### 5\. `rrtools::use_analysis()` 158 | 159 | - this function has three `location =` options: `top_level` to create 160 | a top-level `analysis/` directory, `inst` to create an `inst/` 161 | directory (so that all the sub-directories are available after the 162 | package is installed), and `vignettes` to create a `vignettes/` 163 | directory (and automatically update the `DESCRIPTION`). The default 164 | is a top-level `analysis/`. 165 | - for each option, the contents of the sub-directories are the same, 166 | with the following (using the default `analysis/` for example): 167 | 168 | 169 | 170 | analysis/ 171 | | 172 | ├── paper/ 173 | │ ├── paper.Rmd # this is the main document to edit 174 | │ └── references.bib # this contains the reference list information 175 | 176 | ├── figures/ # location of the figures produced by the Rmd 177 | | 178 | ├── data/ 179 | │ ├── raw_data/ # data obtained from elsewhere 180 | │ └── derived_data/ # data generated during the analysis 181 | | 182 | └── templates 183 | ├── journal-of-archaeological-science.csl 184 | | # this sets the style of citations & reference list 185 | ├── template.docx # used to style the output of the paper.Rmd 186 | └── template.Rmd 187 | 188 | - the `paper.Rmd` is ready to write in and render with bookdown. It 189 | includes: 190 | - a YAML header that identifies the `references.bib` file and the 191 | supplied `csl` file (to style the reference list) 192 | - a colophon that adds some git commit details to the end of the 193 | document. This means that the output file (HTML/PDF/Word) is 194 | always traceable to a specific state of the code. 195 | - the `references.bib` file has just one item to demonstrate the 196 | format. It is ready to insert more reference details. 197 | - you can replace the supplied `csl` file with a different citation 198 | style from 199 | - we recommend using the [citr addin](https://github.com/crsh/citr) 200 | and [Zotero](https://www.zotero.org/) to efficiently insert 201 | citations while writing in an Rmd file 202 | - remember that the `Imports:` field in the `DESCRIPTION` file must 203 | include the names of all packages used in analysis documents (e.g. 204 | `paper.Rmd`). We have a helper function 205 | `rrtools::add_dependencies_to_description()` that will scan the Rmd 206 | file, identify libraries used in there, and add them to the 207 | `DESCRIPTION` file. 208 | - this function has an `data_in_git =` argument, which is `TRUE` by 209 | default. If set to `FALSE` you will exclude files in the `data/` 210 | directory from being tracked by git and prevent them from appearing 211 | on GitHub. You should set `data_in_git = FALSE` if your data files 212 | are large (\>100 mb is the limit for GitHub) or you do not want to 213 | make the data files publicly accessible on GitHub. 214 | - if you’re writing a PhD thesis, replace 215 | `rrtools::use_analysis()` with `rmarkdown::draft('index.Rmd', 216 | template = 'thesis', package = 'huskydown', create_dir = TRUE)` 217 | to create a thesis template from the [huskydown 218 | package](https://github.com/benmarwick/huskydown) 219 | - To load your custom code in the `paper.Rmd`, you have a few 220 | options. You can write all your R code in chunks in the Rmd, 221 | that’s the simplest method. Or you can write R code in script 222 | files in `/R`, and include `devtools::load_all(".")` at the top 223 | of your `paper.Rmd`. Or you can write functions in `/R` and use 224 | `library(pkgname)` at the top of your `paper.Rmd`, or omit 225 | `library` and preface each function call with `pkgname::`. Up to 226 | you to choose whatever seems most natural to you. 227 | 228 | #### 6\. `rrtools::use_dockerfile()` 229 | 230 | - this creates a basic Dockerfile using 231 | [`rocker/verse`](https://github.com/rocker-org/rocker) as the base 232 | image 233 | - the version of R in your rocker container will match the version 234 | used when you run this function (e.g., `rocker/verse:3.5.0`) 235 | - [`rocker/verse`](https://github.com/rocker-org/rocker) includes R, 236 | the [tidyverse](http://tidyverse.org/), RStudio, pandoc and LaTeX, 237 | so compendium build times are very fast on travis 238 | - we need to: 239 | - edit the Dockerfile to add linux dependencies (for R packages 240 | that require additional libraries outside of R). You can find 241 | out what these are by browsing the [DESCRIPTION](DESCRIPTION) 242 | files of the other packages you’re using, and looking in the 243 | SystemRequirements field for each package. If you are getting 244 | build errors on travis, check the logs. Often, the error 245 | messages will include the names of missing libraries. 246 | - modify which Rmd files are rendered when the container is made 247 | - have a public GitHub repo to use the Dockerfile that this 248 | function generates. It is possible to keep the repository 249 | private and run a local Docker container with minor 250 | modifications to the Dockerfile that this function generates. Or 251 | we can use `rrtools::use_circleci()` to build our Docker 252 | container privately at , from a private 253 | GitHub repo. 254 | - If we want to use Travis on our project, we need to make an account 255 | at to receive our Docker container after a 256 | successful build on travis 257 | 258 | #### 7\. `rrtools::use_travis()` 259 | 260 | - this creates a minimal `.travis.yml` file. By default it configures 261 | travis to build our Docker container from our Dockerfile, and build, 262 | install and run our custom package in this container. By specifying 263 | `docker = FALSE` in this function, the travis file will not use 264 | Docker in travis, but run R directly on the travis infrastructure. 265 | We recommend using Docker because it offers greater computational 266 | isolation and saves a substantial amount of time during the travis 267 | build because the base image contains many pre-compiled packages. 268 | - we need to: 269 | - go to to connect to our repo 270 | - add environment variables to enable push of the Docker container 271 | to the Docker Hub 272 | - make an account at to host our Docker 273 | container 274 | - Note that you should run this function only when we are ready for 275 | our GitHub repository to be public. The free travis service we’re 276 | using here requires your GitHub repository to be public. It will not 277 | work on private repositories. If you want to keep your GitHub repo 278 | private until after publication, you can use 279 | `rrtools::use_circleci()` for running free private continuous 280 | integration tests at , instead of travis. With 281 | `rrtools::use_circleci(docker_hub = FALSE)` we can stop our Docker 282 | container from appearing on Docker Hub, so our Docker container 283 | stays completely private. 284 | 285 | #### 8\. `usethis::use_testthat()` 286 | 287 | - if you add functions in `R/`, include tests to ensure they function 288 | as intended 289 | - create tests.R in `tests/testthat/` and check 290 | for template 291 | 292 | You should be able to follow these steps to get a new research 293 | compendium repository connected to travis and ready to write in just a 294 | few minutes. 295 | 296 | ## References 297 | 298 | Kitzes, J., Turek, D., & Deniz, F. (Eds.). (2017). *The Practice of 299 | Reproducible Research: Case Studies and Lessons from the Data-Intensive 300 | Sciences*. Oakland, CA: University of California Press. 301 | 302 | 303 | Marwick, B. (2017). Computational reproducibility in archaeological 304 | research: Basic principles and a case study of their implementation. 305 | *Journal of Archaeological Method and Theory*, 24(2), 424-450. 306 | 307 | 308 | Marwick, B., Boettiger, C. & L. Mullen (2017). Packaging data analytical 309 | work reproducibly using R (and friends). *PeerJ Preprints* 5:e3192v1 310 | 311 | 312 | Piccolo, S. R. and M. B. Frampton (2016). “Tools and techniques for 313 | computational reproducibility.” GigaScience 5(1): 30. 314 | 315 | 316 | rOpenSci community (2017a). Reproducibility in Science A Guide to 317 | enhancing reproducibility in scientific results and writing. Online at 318 | 319 | 320 | rOpenSci community (2017b). rrrpkg: Use of an R package to facilitate 321 | reproducible research. Online at 322 | 323 | Stodden, V. & Miguez, S., (2014). Best Practices for Computational 324 | Science: Software Infrastructure and Environments for Reproducible and 325 | Extensible Research. Journal of Open Research Software. 2(1), p.e21. 326 | DOI: 327 | 328 | Wickham, H. (2017) *Research compendia*. Note prepared for the 2017 329 | rOpenSci Unconf. 330 | 331 | 332 | Wilson G, Bryan J, Cranston K, Kitzes J, Nederbragt L, et al. (2017). 333 | Good enough practices in scientific computing. *PLOS Computational 334 | Biology* 13(6): e1005510. 335 | 336 | ## Contributing 337 | 338 | If you would like to contribute to this project, please start by reading 339 | our [Guide to Contributing](CONTRIBUTING.md). Please note that this 340 | project is released with a [Contributor Code of Conduct](CONDUCT.md). By 341 | participating in this project you agree to abide by its terms. 342 | 343 | ## Acknowledgements 344 | 345 | This project was developed during the 2017 Summer School on Reproducible 346 | Research in Landscape Archaeology at the Freie Universität Berlin (17-21 347 | July), funded and jointly organized by [Exc264 348 | Topoi](https://www.topoi.org/), 349 | [CRC1266](http://www.sfb1266.uni-kiel.de/en), and 350 | [ISAAKiel](https://isaakiel.github.io/). Special thanks to [Sophie C. 351 | Schmidt](https://github.com/SCSchmidt) for help. The convenience 352 | functions in this package are inspired by similar functions in the 353 | [`usethis`](https://github.com/r-lib/usethis) package. 354 | --------------------------------------------------------------------------------