├── .Rbuildignore
├── .github
├── .gitignore
└── workflows
│ └── bookdown.yaml
├── .gitignore
├── README.md
├── _bookdown.yml
├── _output.yml
├── book.bib
├── header-only.Rmd
├── index.Rmd
├── introduction.Rmd
├── packages.bib
├── preamble.tex
├── r-extensions.Rproj
├── renv.lock
├── renv
└── activate.R
├── standalone.Rmd
├── style.css
└── top-level.Rmd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^renv$
2 | ^renv\.lock$
3 | ^\.github$
4 |
--------------------------------------------------------------------------------
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/.github/workflows/bookdown.yaml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches: master
4 |
5 | name: bookdown
6 |
7 | jobs:
8 | build:
9 | runs-on: macOS-latest
10 | steps:
11 | - name: Checkout repo
12 | uses: actions/checkout@v2
13 |
14 | - name: Setup R
15 | uses: r-lib/actions/setup-r@master
16 |
17 | - name: Install pandoc and pandoc citeproc
18 | run: |
19 | brew install pandoc
20 | brew install pandoc-citeproc
21 |
22 | - name: Cache Renv packages
23 | uses: actions/cache@v1
24 | with:
25 | path: ~/Library/Application Support/renv
26 | key: r-3-${{ hashFiles('renv.lock') }}
27 | restore-keys: r-3-
28 |
29 | - name: Cache bookdown results
30 | uses: actions/cache@v1
31 | with:
32 | path: _bookdown_files
33 | key: bookdown-${{ hashFiles('**/*Rmd') }}
34 | restore-keys: bookdown-
35 |
36 | - name: Install packages
37 | run: |
38 | R -e 'install.packages("renv")'
39 | R -e 'renv::consent(provided = TRUE)'
40 | R -e 'renv::restore()'
41 |
42 | - name: Build site
43 | run: Rscript -e 'bookdown::render_book("index.Rmd", quiet = TRUE)'
44 |
45 | - name: Install npm
46 | uses: actions/setup-node@v1
47 |
48 | - name: Deploy to Netlify
49 | # NETLIFY_AUTH_TOKEN and NETLIFY_SITE_ID added in the repo's secrets
50 | env:
51 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
52 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
53 | run: |
54 | npm install netlify-cli -g
55 | netlify deploy --prod --dir _book
56 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rhistory
2 | .RData
3 | .Rproj.user
4 | _book
5 | _bookdown_files
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This will hopefully become a small book of examples on how to embed different types of C++ third party libraries into an R package.
--------------------------------------------------------------------------------
/_bookdown.yml:
--------------------------------------------------------------------------------
1 | book_filename: "r-extensions"
2 | delete_merged_file: true
3 | language:
4 | ui:
5 | chapter_name: "Chapter "
6 |
7 | rmd_files:
8 | [
9 | "index.Rmd",
10 |
11 | "introduction.Rmd",
12 |
13 | "header-only.Rmd",
14 | "top-level.Rmd",
15 | "standalone.Rmd"
16 | ]
--------------------------------------------------------------------------------
/_output.yml:
--------------------------------------------------------------------------------
1 | bookdown::gitbook:
2 | css: style.css
3 | config:
4 | toc:
5 | before: |
6 |
R Extensions
7 | after: |
8 | Published with bookdown
9 | download: ["pdf", "epub"]
10 | bookdown::pdf_book:
11 | includes:
12 | in_header: preamble.tex
13 | latex_engine: xelatex
14 | citation_package: natbib
15 | keep_tex: yes
16 | bookdown::epub_book: default
17 |
--------------------------------------------------------------------------------
/book.bib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DavisVaughan/r-extensions/9e8e611337ea2d5fbabff3d92685bbccd24305e2/book.bib
--------------------------------------------------------------------------------
/header-only.Rmd:
--------------------------------------------------------------------------------
1 | # Header Only {#header-only}
2 |
--------------------------------------------------------------------------------
/index.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "R Extensions"
3 | author: "Davis Vaughan"
4 | date: "`r Sys.Date()`"
5 | site: bookdown::bookdown_site
6 | documentclass: book
7 | bibliography: [book.bib, packages.bib]
8 | biblio-style: apalike
9 | link-citations: yes
10 | description: "This is a book of examples for embedding different types of third party C++ libraries into R packages."
11 | ---
12 |
13 | # Welcome {-#welcome}
14 |
15 | Some intro stuff here....
--------------------------------------------------------------------------------
/introduction.Rmd:
--------------------------------------------------------------------------------
1 | # Introduction {#intro}
2 |
3 | Some introduction material here...
--------------------------------------------------------------------------------
/packages.bib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DavisVaughan/r-extensions/9e8e611337ea2d5fbabff3d92685bbccd24305e2/packages.bib
--------------------------------------------------------------------------------
/preamble.tex:
--------------------------------------------------------------------------------
1 | \usepackage{booktabs}
2 |
--------------------------------------------------------------------------------
/r-extensions.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: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | StripTrailingWhitespace: Yes
16 |
17 | BuildType: Website
18 |
--------------------------------------------------------------------------------
/renv.lock:
--------------------------------------------------------------------------------
1 | {
2 | "R": {
3 | "Version": "3.6.0",
4 | "Repositories": [
5 | {
6 | "Name": "CRAN",
7 | "URL": "https://cran.rstudio.com"
8 | }
9 | ]
10 | },
11 | "Packages": {
12 | "Rcpp": {
13 | "Package": "Rcpp",
14 | "Version": "1.0.4.6",
15 | "Source": "Repository",
16 | "Repository": "CRAN",
17 | "Hash": "e652f23d8b1807cc975c51410d05b72f"
18 | },
19 | "base64enc": {
20 | "Package": "base64enc",
21 | "Version": "0.1-3",
22 | "Source": "Repository",
23 | "Repository": "CRAN",
24 | "Hash": "543776ae6848fde2f48ff3816d0628bc"
25 | },
26 | "bookdown": {
27 | "Package": "bookdown",
28 | "Version": "0.18",
29 | "Source": "Repository",
30 | "Repository": "CRAN",
31 | "Hash": "72e9c52caf3f7aacb4e368b75f6ec72a"
32 | },
33 | "digest": {
34 | "Package": "digest",
35 | "Version": "0.6.25",
36 | "Source": "Repository",
37 | "Repository": "CRAN",
38 | "Hash": "f697db7d92b7028c4b3436e9603fb636"
39 | },
40 | "evaluate": {
41 | "Package": "evaluate",
42 | "Version": "0.14",
43 | "Source": "Repository",
44 | "Repository": "CRAN",
45 | "Hash": "ec8ca05cffcc70569eaaad8469d2a3a7"
46 | },
47 | "glue": {
48 | "Package": "glue",
49 | "Version": "1.4.0",
50 | "Source": "Repository",
51 | "Repository": "CRAN",
52 | "Hash": "2aefa994e8df5da17dc09afd80f924d5"
53 | },
54 | "highr": {
55 | "Package": "highr",
56 | "Version": "0.8",
57 | "Source": "Repository",
58 | "Repository": "CRAN",
59 | "Hash": "4dc5bb88961e347a0f4d8aad597cbfac"
60 | },
61 | "htmltools": {
62 | "Package": "htmltools",
63 | "Version": "0.4.0",
64 | "Source": "Repository",
65 | "Repository": "CRAN",
66 | "Hash": "2d7691222f82f41e93f6d30f169bd5e1"
67 | },
68 | "jsonlite": {
69 | "Package": "jsonlite",
70 | "Version": "1.6.1",
71 | "Source": "Repository",
72 | "Repository": "CRAN",
73 | "Hash": "84b0ee361e2f78d6b7d670db9471c0c5"
74 | },
75 | "knitr": {
76 | "Package": "knitr",
77 | "Version": "1.28",
78 | "Source": "Repository",
79 | "Repository": "CRAN",
80 | "Hash": "915a6f0134cdbdf016d7778bc80b2eda"
81 | },
82 | "magrittr": {
83 | "Package": "magrittr",
84 | "Version": "1.5",
85 | "Source": "Repository",
86 | "Repository": "CRAN",
87 | "Hash": "1bb58822a20301cee84a41678e25d9b7"
88 | },
89 | "markdown": {
90 | "Package": "markdown",
91 | "Version": "1.1",
92 | "Source": "Repository",
93 | "Repository": "CRAN",
94 | "Hash": "61e4a10781dd00d7d81dd06ca9b94e95"
95 | },
96 | "mime": {
97 | "Package": "mime",
98 | "Version": "0.9",
99 | "Source": "Repository",
100 | "Repository": "CRAN",
101 | "Hash": "e87a35ec73b157552814869f45a63aa3"
102 | },
103 | "renv": {
104 | "Package": "renv",
105 | "Version": "0.9.3",
106 | "Source": "Repository",
107 | "Repository": "CRAN",
108 | "Hash": "c1a367437d8a8a44bec4b9d4974cb20c"
109 | },
110 | "rlang": {
111 | "Package": "rlang",
112 | "Version": "0.4.5",
113 | "Source": "Repository",
114 | "Repository": "CRAN",
115 | "Hash": "1cc1b38e4db40ea6eb19ab8080bbed3b"
116 | },
117 | "rmarkdown": {
118 | "Package": "rmarkdown",
119 | "Version": "2.1",
120 | "Source": "Repository",
121 | "Repository": "CRAN",
122 | "Hash": "9d1c61d476c448350c482d6664e1b28b"
123 | },
124 | "stringi": {
125 | "Package": "stringi",
126 | "Version": "1.4.6",
127 | "Source": "Repository",
128 | "Repository": "CRAN",
129 | "Hash": "e99d8d656980d2dd416a962ae55aec90"
130 | },
131 | "stringr": {
132 | "Package": "stringr",
133 | "Version": "1.4.0",
134 | "Source": "Repository",
135 | "Repository": "CRAN",
136 | "Hash": "0759e6b6c0957edb1311028a49a35e76"
137 | },
138 | "tinytex": {
139 | "Package": "tinytex",
140 | "Version": "0.21",
141 | "Source": "Repository",
142 | "Repository": "CRAN",
143 | "Hash": "02e11a2e5d05f1d5ab19394f19ab2999"
144 | },
145 | "xfun": {
146 | "Package": "xfun",
147 | "Version": "0.12",
148 | "Source": "Repository",
149 | "Repository": "CRAN",
150 | "Hash": "ccd8453a7b9e380628f6cd2862e46cad"
151 | },
152 | "yaml": {
153 | "Package": "yaml",
154 | "Version": "2.2.1",
155 | "Source": "Repository",
156 | "Repository": "CRAN",
157 | "Hash": "2826c5d9efb0a88f657c7a679c7106db"
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/renv/activate.R:
--------------------------------------------------------------------------------
1 |
2 | local({
3 |
4 | # the requested version of renv
5 | version <- "0.9.3"
6 |
7 | # avoid recursion
8 | if (!is.na(Sys.getenv("RENV_R_INITIALIZING", unset = NA)))
9 | return(invisible(TRUE))
10 |
11 | # signal that we're loading renv during R startup
12 | Sys.setenv("RENV_R_INITIALIZING" = "true")
13 | on.exit(Sys.unsetenv("RENV_R_INITIALIZING"), add = TRUE)
14 |
15 | # signal that we've consented to use renv
16 | options(renv.consent = TRUE)
17 |
18 | # load the 'utils' package eagerly -- this ensures that renv shims, which
19 | # mask 'utils' packages, will come first on the search path
20 | library(utils, lib.loc = .Library)
21 |
22 | # check to see if renv has already been loaded
23 | if ("renv" %in% loadedNamespaces()) {
24 |
25 | # if renv has already been loaded, and it's the requested version of renv,
26 | # nothing to do
27 | spec <- .getNamespaceInfo(.getNamespace("renv"), "spec")
28 | if (identical(spec[["version"]], version))
29 | return(invisible(TRUE))
30 |
31 | # otherwise, unload and attempt to load the correct version of renv
32 | unloadNamespace("renv")
33 |
34 | }
35 |
36 | # construct path to renv in library
37 | libpath <- local({
38 |
39 | root <- Sys.getenv("RENV_PATHS_LIBRARY", unset = "renv/library")
40 | prefix <- paste("R", getRversion()[1, 1:2], sep = "-")
41 |
42 | # include SVN revision for development versions of R
43 | # (to avoid sharing platform-specific artefacts with released versions of R)
44 | devel <-
45 | identical(R.version[["status"]], "Under development (unstable)") ||
46 | identical(R.version[["nickname"]], "Unsuffered Consequences")
47 |
48 | if (devel)
49 | prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r")
50 |
51 | file.path(root, prefix, R.version$platform)
52 |
53 | })
54 |
55 | # try to load renv from the project library
56 | if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
57 |
58 | # warn if the version of renv loaded does not match
59 | loadedversion <- utils::packageDescription("renv", fields = "Version")
60 | if (version != loadedversion) {
61 |
62 | # assume four-component versions are from GitHub; three-component
63 | # versions are from CRAN
64 | components <- strsplit(loadedversion, "[.-]")[[1]]
65 | remote <- if (length(components) == 4L)
66 | paste("rstudio/renv", loadedversion, sep = "@")
67 | else
68 | paste("renv", loadedversion, sep = "@")
69 |
70 | fmt <- paste(
71 | "renv %1$s was loaded from project library, but renv %2$s is recorded in lockfile.",
72 | "Use `renv::record(\"%3$s\")` to record this version in the lockfile.",
73 | "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.",
74 | sep = "\n"
75 | )
76 |
77 | msg <- sprintf(fmt, loadedversion, version, remote)
78 | warning(msg, call. = FALSE)
79 |
80 | }
81 |
82 | # load the project
83 | return(renv::load())
84 |
85 | }
86 |
87 | # failed to find renv locally; we'll try to install from GitHub.
88 | # first, set up download options as appropriate (try to use GITHUB_PAT)
89 | install_renv <- function() {
90 |
91 | message("Failed to find installation of renv -- attempting to bootstrap...")
92 |
93 | # ensure .Rprofile doesn't get executed
94 | rpu <- Sys.getenv("R_PROFILE_USER", unset = NA)
95 | Sys.setenv(R_PROFILE_USER = "")
96 | on.exit({
97 | if (is.na(rpu))
98 | Sys.unsetenv("R_PROFILE_USER")
99 | else
100 | Sys.setenv(R_PROFILE_USER = rpu)
101 | }, add = TRUE)
102 |
103 | # prepare download options
104 | pat <- Sys.getenv("GITHUB_PAT")
105 | if (nzchar(Sys.which("curl")) && nzchar(pat)) {
106 | fmt <- "--location --fail --header \"Authorization: token %s\""
107 | extra <- sprintf(fmt, pat)
108 | saved <- options("download.file.method", "download.file.extra")
109 | options(download.file.method = "curl", download.file.extra = extra)
110 | on.exit(do.call(base::options, saved), add = TRUE)
111 | } else if (nzchar(Sys.which("wget")) && nzchar(pat)) {
112 | fmt <- "--header=\"Authorization: token %s\""
113 | extra <- sprintf(fmt, pat)
114 | saved <- options("download.file.method", "download.file.extra")
115 | options(download.file.method = "wget", download.file.extra = extra)
116 | on.exit(do.call(base::options, saved), add = TRUE)
117 | }
118 |
119 | # fix up repos
120 | repos <- getOption("repos")
121 | on.exit(options(repos = repos), add = TRUE)
122 | repos[repos == "@CRAN@"] <- "https://cloud.r-project.org"
123 | options(repos = repos)
124 |
125 | # check for renv on CRAN matching this version
126 | db <- as.data.frame(available.packages(), stringsAsFactors = FALSE)
127 | if ("renv" %in% rownames(db)) {
128 | entry <- db["renv", ]
129 | if (identical(entry$Version, version)) {
130 | message("* Installing renv ", version, " ... ", appendLF = FALSE)
131 | dir.create(libpath, showWarnings = FALSE, recursive = TRUE)
132 | utils::install.packages("renv", lib = libpath, quiet = TRUE)
133 | message("Done!")
134 | return(TRUE)
135 | }
136 | }
137 |
138 | # try to download renv
139 | message("* Downloading renv ", version, " ... ", appendLF = FALSE)
140 | prefix <- "https://api.github.com"
141 | url <- file.path(prefix, "repos/rstudio/renv/tarball", version)
142 | destfile <- tempfile("renv-", fileext = ".tar.gz")
143 | on.exit(unlink(destfile), add = TRUE)
144 | utils::download.file(url, destfile = destfile, mode = "wb", quiet = TRUE)
145 | message("Done!")
146 |
147 | # attempt to install it into project library
148 | message("* Installing renv ", version, " ... ", appendLF = FALSE)
149 | dir.create(libpath, showWarnings = FALSE, recursive = TRUE)
150 |
151 | # invoke using system2 so we can capture and report output
152 | bin <- R.home("bin")
153 | exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R"
154 | r <- file.path(bin, exe)
155 | args <- c("--vanilla", "CMD", "INSTALL", "-l", shQuote(libpath), shQuote(destfile))
156 | output <- system2(r, args, stdout = TRUE, stderr = TRUE)
157 | message("Done!")
158 |
159 | # check for successful install
160 | status <- attr(output, "status")
161 | if (is.numeric(status) && !identical(status, 0L)) {
162 | text <- c("Error installing renv", "=====================", output)
163 | writeLines(text, con = stderr())
164 | }
165 |
166 |
167 | }
168 |
169 | try(install_renv())
170 |
171 | # try again to load
172 | if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
173 | message("Successfully installed and loaded renv ", version, ".")
174 | return(renv::load())
175 | }
176 |
177 | # failed to download or load renv; warn the user
178 | msg <- c(
179 | "Failed to find an renv installation: the project will not be loaded.",
180 | "Use `renv::activate()` to re-initialize the project."
181 | )
182 |
183 | warning(paste(msg, collapse = "\n"), call. = FALSE)
184 |
185 | })
186 |
--------------------------------------------------------------------------------
/standalone.Rmd:
--------------------------------------------------------------------------------
1 | # Standalone Libraries {#standalone}
2 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | p.caption {
2 | color: #777;
3 | margin-top: 10px;
4 | }
5 | p code {
6 | white-space: inherit;
7 | }
8 | pre {
9 | word-break: normal;
10 | word-wrap: normal;
11 | }
12 | pre code {
13 | white-space: inherit;
14 | }
15 |
--------------------------------------------------------------------------------
/top-level.Rmd:
--------------------------------------------------------------------------------
1 | # Top Level Embedding {#top-level}
2 |
--------------------------------------------------------------------------------