From 032b4e297e021d961c1a41b7b8e7ae334fa8f749 Mon Sep 17 00:00:00 2001 From: jennybc Date: Mon, 22 Jan 2024 07:16:50 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20hadley/r?= =?UTF-8?q?-pkgs@b6391ae1c56fafb3f9f3b519a923880111856849=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dependencies-mindset-background.adoc | 2 +- book-asciidoc/package-within.adoc | 10 +- book-asciidoc/preface.adoc | 2 +- book-asciidoc/website.adoc | 8 +- book-asciidoc/whole-game.adoc | 22 ++-- dependencies-mindset-background.html | 2 +- package-within.html | 10 +- preface.html | 2 +- search.json | 24 ++-- sitemap.xml | 108 +++++++++--------- website.html | 8 +- whole-game.html | 22 ++-- 12 files changed, 110 insertions(+), 110 deletions(-) diff --git a/book-asciidoc/dependencies-mindset-background.adoc b/book-asciidoc/dependencies-mindset-background.adoc index 7c62ad1c9..e6cf00559 100644 --- a/book-asciidoc/dependencies-mindset-background.adoc +++ b/book-asciidoc/dependencies-mindset-background.adoc @@ -210,7 +210,7 @@ sd #> function (x, na.rm = FALSE) #> sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x), #> na.rm = na.rm)) -#> +#> #> ---- diff --git a/book-asciidoc/package-within.adoc b/book-asciidoc/package-within.adoc index a8164e45c..85694a904 100644 --- a/book-asciidoc/package-within.adoc +++ b/book-asciidoc/package-within.adoc @@ -75,7 +75,7 @@ Finally, this cleaned (cleaner?) data is written back out to a CSV file. They li now <- Sys.time() timestamp <- format(now, "%Y-%B-%d_%H-%M-%S") (outfile <- paste0(timestamp, "_", sub("(.*)([.]csv$)", "\\1_clean\\2", infile))) -#> [1] "2024-January-21_07-14-29_swim_clean.csv" +#> [1] "2024-January-22_07-14-13_swim_clean.csv" write.csv(dat, file = outfile, quote = FALSE, row.names = FALSE) ---- @@ -503,7 +503,7 @@ The timestamps now reflect the current time, but the group raises a new concern. [source,r,cell-code] ---- format(Sys.time(), "%Y-%B-%d_%H-%M-%S") -#> [1] "2024-January-21_07-14-30" +#> [1] "2024-January-22_07-14-14" ---- This formats `+Sys.time()+` in such a way that it includes the month _name_ (not number) and the local timefootnote:[It would clearly be better to format according to ISO 8601, which encodes the month by number, but please humor me for the sake of making this example more obvious.]. @@ -545,7 +545,7 @@ format(Sys.time(), "%Y-%B-%d_%H-%M-%S") ---- .... -#> [1] "2024-janeiro-21_04-14-30" +#> [1] "2024-janeiro-22_04-14-14" .... After: @@ -553,10 +553,10 @@ After: [source,r,cell-code] ---- outfile_path("INFILE.csv") -#> [1] "2024-January-21_07-14-30_INFILE_clean.csv" +#> [1] "2024-January-22_07-14-14_INFILE_clean.csv" format(Sys.time(), "%Y-%B-%d_%H-%M-%S") -#> [1] "2024-January-21_07-14-30" +#> [1] "2024-January-22_07-14-14" ---- Notice that her month name switched from Portuguese to English and the time is clearly being reported in a different time zone. The calls to `+Sys.setlocale()+` and `+Sys.setenv()+` inside `+timestamp()+` have made persistent (and very surprising) changes to her R session. This sort of side effect is very undesirable and is extremely difficult to track down and debug, especially in more complicated settings. diff --git a/book-asciidoc/preface.adoc b/book-asciidoc/preface.adoc index db046e1e0..828be746b 100644 --- a/book-asciidoc/preface.adoc +++ b/book-asciidoc/preface.adoc @@ -113,7 +113,7 @@ devtools::session_info() #> collate C.UTF-8 #> ctype C.UTF-8 #> tz UTC -#> date 2024-01-21 +#> date 2024-01-22 #> pandoc 2.9.2.1 @ /usr/bin/ (via rmarkdown) #> #> ─ Packages ─────────────────────────────────────────────────────── diff --git a/book-asciidoc/website.adoc b/book-asciidoc/website.adoc index 4a10da137..9cd4f794b 100644 --- a/book-asciidoc/website.adoc +++ b/book-asciidoc/website.adoc @@ -31,7 +31,7 @@ usethis::use_pkgdown() ---- .... -#> ✔ Setting active project to '/tmp/Rtmpk7FgIJ/mypackage' +#> ✔ Setting active project to '/tmp/Rtmp1xaeZq/mypackage' #> ✔ Adding '^_pkgdown\\.yml$', '^docs$', '^pkgdown$' to '.Rbuildignore' #> ✔ Adding 'docs' to '.gitignore' #> ✔ Writing '_pkgdown.yml' @@ -53,11 +53,11 @@ pkgdown::build_site() ---- .... -#> ✔ Setting active project to '/tmp/Rtmpk7FgIJ/mypackage' +#> ✔ Setting active project to '/tmp/Rtmp1xaeZq/mypackage' #> -- Installing package into temporary library ----------------------- #> == Building pkgdown site ======================================================= -#> Reading from: '/tmp/Rtmpk7FgIJ/mypackage' -#> Writing to: '/tmp/Rtmpk7FgIJ/mypackage/docs' +#> Reading from: '/tmp/Rtmp1xaeZq/mypackage' +#> Writing to: '/tmp/Rtmp1xaeZq/mypackage/docs' #> -- Initialising site ----------------------------------------------------------- #> Copying '../../../home/runner/work/_temp/Library/pkgdown/BS5/assets/link.svg' to 'link.svg' #> Copying '../../../home/runner/work/_temp/Library/pkgdown/BS5/assets/pkgdown.js' to 'pkgdown.js' diff --git a/book-asciidoc/whole-game.adoc b/book-asciidoc/whole-game.adoc index 7b3bc7a2c..2600bd757 100644 --- a/book-asciidoc/whole-game.adoc +++ b/book-asciidoc/whole-game.adoc @@ -71,8 +71,8 @@ create_package("~/path/to/regexcite") For the creation of this book we have to work in a temporary directory, because the book is built non-interactively in the cloud. Behind the scenes, we’re executing our own `+create_package()+` command, but don’t be surprised if our output differs a bit from yours. .... -#> ✔ Creating '/tmp/RtmpcPon17/regexcite/' -#> ✔ Setting active project to '/tmp/RtmpcPon17/regexcite' +#> ✔ Creating '/tmp/RtmpKsGTjT/regexcite/' +#> ✔ Setting active project to '/tmp/RtmpKsGTjT/regexcite' #> ✔ Creating 'R/' #> ✔ Writing 'DESCRIPTION' #> Package: regexcite @@ -162,7 +162,7 @@ Click on History (the clock icon in the Git pane) and, if you consented, you wil [width="100%",cols="<21%,<59%,<20%",options="header",] |=== |commit |author |message -|d3ed67cfce… |jennybc jennybc@users.noreply.github.com |Initial commit +|1ebacb2c8d… |jennybc jennybc@users.noreply.github.com |Initial commit |=== [TIP] @@ -333,7 +333,7 @@ check() .... ── R CMD check results ─────────────────── regexcite 0.0.0.9000 ──── -Duration: 7.3s +Duration: 6.4s ❯ checking DESCRIPTION meta-information ... WARNING Non-standard license specification: @@ -516,7 +516,7 @@ check() .... ── R CMD check results ─────────────────── regexcite 0.0.0.9000 ──── -Duration: 8.8s +Duration: 7.9s 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ .... @@ -532,14 +532,14 @@ install() .... ── R CMD build ───────────────────────────────────────────────────── -* checking for file ‘/tmp/RtmpcPon17/regexcite/DESCRIPTION’ ... OK +* checking for file ‘/tmp/RtmpKsGTjT/regexcite/DESCRIPTION’ ... OK * preparing ‘regexcite’: * checking DESCRIPTION meta-information ... OK * checking for LF line-endings in source and make files and shell scripts * checking for empty or unneeded directories * building ‘regexcite_0.0.0.9000.tar.gz’ Running /opt/R/4.3.2/lib/R/bin/R CMD INSTALL \ - /tmp/RtmpcPon17/regexcite_0.0.0.9000.tar.gz --install-tests + /tmp/RtmpKsGTjT/regexcite_0.0.0.9000.tar.gz --install-tests * installing to library ‘/home/runner/work/_temp/Library’ * installing *source* package ‘regexcite’ ... ** using staged installation @@ -896,7 +896,7 @@ The very best way to render `+README.Rmd+` is with `+build_readme()+`, because i ---- build_readme() #> ℹ Installing regexcite in temporary library -#> ℹ Building '/tmp/RtmpcPon17/regexcite/README.Rmd' +#> ℹ Building '/tmp/RtmpKsGTjT/regexcite/README.Rmd' ---- You can see the rendered `+README.md+` simply by https://github.com/jennybc/regexcite#readme[visiting regexcite on GitHub]. @@ -914,7 +914,7 @@ check() .... ── R CMD check results ─────────────────── regexcite 0.0.0.9000 ──── -Duration: 10.1s +Duration: 9.3s 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ .... @@ -928,7 +928,7 @@ install() .... ── R CMD build ───────────────────────────────────────────────────── -* checking for file ‘/tmp/RtmpcPon17/regexcite/DESCRIPTION’ ... OK +* checking for file ‘/tmp/RtmpKsGTjT/regexcite/DESCRIPTION’ ... OK * preparing ‘regexcite’: * checking DESCRIPTION meta-information ... OK * checking for LF line-endings in source and make files and shell scripts @@ -936,7 +936,7 @@ install() Removed empty directory ‘regexcite/tests/testthat/_snaps’ * building ‘regexcite_0.0.0.9000.tar.gz’ Running /opt/R/4.3.2/lib/R/bin/R CMD INSTALL \ - /tmp/RtmpcPon17/regexcite_0.0.0.9000.tar.gz --install-tests + /tmp/RtmpKsGTjT/regexcite_0.0.0.9000.tar.gz --install-tests * installing to library ‘/home/runner/work/_temp/Library’ * installing *source* package ‘regexcite’ ... ** using staged installation diff --git a/dependencies-mindset-background.html b/dependencies-mindset-background.html index 6f4b7c67b..ffe5c454f 100644 --- a/dependencies-mindset-background.html +++ b/dependencies-mindset-background.html @@ -595,7 +595,7 @@

#> function (x, na.rm = FALSE) #> sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x), #> na.rm = na.rm)) -#> <bytecode: 0x563f6ecf3080> +#> <bytecode: 0x55f465913560> #> <environment: namespace:stats>

It’s defined in terms of another function, var(), also from the stats package. So what happens if we override var() with our own definition? Does it break sd()?

diff --git a/package-within.html b/package-within.html index 94fde0d46..3e01fe238 100644 --- a/package-within.html +++ b/package-within.html @@ -474,7 +474,7 @@

now <- Sys.time()
 timestamp <- format(now, "%Y-%B-%d_%H-%M-%S")
 (outfile <- paste0(timestamp, "_", sub("(.*)([.]csv$)", "\\1_clean\\2", infile)))
-#> [1] "2024-January-21_07-14-26_swim_clean.csv"
+#> [1] "2024-January-22_07-14-10_swim_clean.csv"
 write.csv(dat, file = outfile, quote = FALSE, row.names = FALSE)

Here is data-cleaning.R in its entirety:

@@ -820,7 +820,7 @@

5:

format(Sys.time(), "%Y-%B-%d_%H-%M-%S")
-#> [1] "2024-January-21_07-14-26"
+#> [1] "2024-January-22_07-14-10"

This formats Sys.time() in such a way that it includes the month name (not number) and the local time6.

Table 5.1 shows what happens when such a timestamp is produced by several hypothetical colleagues cleaning some data at exactly the same instant in time.

@@ -892,15 +892,15 @@

format(Sys.time(), "%Y-%B-%d_%H-%M-%S")
-
#> [1] "2024-janeiro-21_04-14-27"
+
#> [1] "2024-janeiro-22_04-14-11"

After:

outfile_path("INFILE.csv")
-#> [1] "2024-January-21_07-14-26_INFILE_clean.csv"
+#> [1] "2024-January-22_07-14-10_INFILE_clean.csv"
 
 format(Sys.time(), "%Y-%B-%d_%H-%M-%S")
-#> [1] "2024-January-21_07-14-27"
+#> [1] "2024-January-22_07-14-11"

Notice that her month name switched from Portuguese to English and the time is clearly being reported in a different time zone. The calls to Sys.setlocale() and Sys.setenv() inside timestamp() have made persistent (and very surprising) changes to her R session. This sort of side effect is very undesirable and is extremely difficult to track down and debug, especially in more complicated settings.

Here are better versions of timestamp():

diff --git a/preface.html b/preface.html index 157db6bf1..74278b988 100644 --- a/preface.html +++ b/preface.html @@ -515,7 +515,7 @@

Prefa #> collate C.UTF-8 #> ctype C.UTF-8 #> tz UTC -#> date 2024-01-21 +#> date 2024-01-22 #> pandoc 2.9.2.1 @ /usr/bin/ (via rmarkdown) #> #> ─ Packages ─────────────────────────────────────────────────────── diff --git a/search.json b/search.json index 884100641..bb0ba4760 100644 --- a/search.json +++ b/search.json @@ -25,7 +25,7 @@ "href": "preface.html#colophon", "title": "Preface", "section": "Colophon", - "text": "Colophon\nThis book was authored using Quarto inside RStudio. The website is hosted with Netlify, and automatically updated after every commit by GitHub actions. The complete source is available from GitHub.\nThis version of the book was built with:\n\nlibrary(devtools)\n#> Loading required package: usethis\nlibrary(roxygen2)\nlibrary(testthat)\n#> \n#> Attaching package: 'testthat'\n#> The following object is masked from 'package:devtools':\n#> \n#> test_file\n#> The following object is masked from 'package:dplyr':\n#> \n#> matches\n#> The following object is masked from 'package:purrr':\n#> \n#> is_null\n#> The following objects are masked from 'package:readr':\n#> \n#> edition_get, local_edition\n#> The following object is masked from 'package:tidyr':\n#> \n#> matches\ndevtools::session_info()\n#> ─ Session info ───────────────────────────────────────────────────\n#> setting value\n#> version R version 4.3.2 (2023-10-31)\n#> os Ubuntu 22.04.3 LTS\n#> system x86_64, linux-gnu\n#> ui X11\n#> language (EN)\n#> collate C.UTF-8\n#> ctype C.UTF-8\n#> tz UTC\n#> date 2024-01-21\n#> pandoc 2.9.2.1 @ /usr/bin/ (via rmarkdown)\n#> \n#> ─ Packages ───────────────────────────────────────────────────────\n#> package * version date (UTC) lib source\n#> bit 4.0.5 2022-11-15 [1] RSPM\n#> bit64 4.0.5 2020-08-30 [1] RSPM\n#> brio 1.1.4 2023-12-10 [1] RSPM\n#> cachem 1.0.8 2023-05-01 [1] RSPM\n#> cli 3.6.2 2023-12-11 [1] RSPM\n#> colorspace 2.1-0 2023-01-23 [1] RSPM\n#> crayon 1.5.2 2022-09-29 [1] RSPM\n#> devtools * 2.4.5 2022-10-11 [1] RSPM\n#> digest 0.6.34 2024-01-11 [1] RSPM\n#> dplyr * 1.1.4 2023-11-17 [1] RSPM\n#> ellipsis 0.3.2 2021-04-29 [1] RSPM\n#> evaluate 0.23 2023-11-01 [1] RSPM\n#> fansi 1.0.6 2023-12-08 [1] RSPM\n#> fastmap 1.1.1 2023-02-24 [1] RSPM\n#> forcats * 1.0.0 2023-01-29 [1] RSPM\n#> fs 1.6.3 2023-07-20 [1] RSPM\n#> generics 0.1.3 2022-07-05 [1] RSPM\n#> ggplot2 * 3.4.4 2023-10-12 [1] RSPM\n#> glue 1.7.0 2024-01-09 [1] RSPM\n#> gtable 0.3.4 2023-08-21 [1] RSPM\n#> hms 1.1.3 2023-03-21 [1] RSPM\n#> htmltools 0.5.7 2023-11-03 [1] RSPM\n#> htmlwidgets 1.6.4 2023-12-06 [1] RSPM\n#> httpuv 1.6.13 2023-12-06 [1] RSPM\n#> jsonlite 1.8.8 2023-12-04 [1] RSPM\n#> knitr 1.45 2023-10-30 [1] RSPM\n#> later 1.3.2 2023-12-06 [1] RSPM\n#> lifecycle 1.0.4 2023-11-07 [1] RSPM\n#> lubridate * 1.9.3 2023-09-27 [1] RSPM\n#> magrittr 2.0.3 2022-03-30 [1] RSPM\n#> memoise 2.0.1 2021-11-26 [1] RSPM\n#> mime 0.12 2021-09-28 [1] RSPM\n#> miniUI 0.1.1.1 2018-05-18 [1] RSPM\n#> munsell 0.5.0 2018-06-12 [1] RSPM\n#> pillar 1.9.0 2023-03-22 [1] RSPM\n#> pkgbuild 1.4.3 2023-12-10 [1] RSPM\n#> pkgconfig 2.0.3 2019-09-22 [1] RSPM\n#> pkgload 1.3.4 2024-01-16 [1] RSPM\n#> profvis 0.3.8 2023-05-02 [1] RSPM\n#> promises 1.2.1 2023-08-10 [1] RSPM\n#> purrr * 1.0.2 2023-08-10 [1] RSPM\n#> R6 2.5.1 2021-08-19 [1] RSPM\n#> Rcpp 1.0.12 2024-01-09 [1] RSPM\n#> readr * 2.1.5 2024-01-10 [1] RSPM\n#> remotes 2.4.2.1 2023-07-18 [1] RSPM\n#> rlang 1.1.3 2024-01-10 [1] RSPM\n#> rmarkdown 2.25 2023-09-18 [1] RSPM\n#> roxygen2 * 7.3.0 2024-01-11 [1] RSPM\n#> scales 1.3.0 2023-11-28 [1] RSPM\n#> sessioninfo 1.2.2 2021-12-06 [1] RSPM\n#> shiny 1.8.0 2023-11-17 [1] RSPM\n#> stringi 1.8.3 2023-12-11 [1] RSPM\n#> stringr * 1.5.1 2023-11-14 [1] RSPM\n#> testthat * 3.2.1 2023-12-02 [1] RSPM\n#> tibble * 3.2.1 2023-03-20 [1] RSPM\n#> tidyr * 1.3.0 2023-01-24 [1] RSPM\n#> tidyselect 1.2.0 2022-10-10 [1] RSPM\n#> tidyverse * 2.0.0 2023-02-22 [1] RSPM\n#> timechange 0.3.0 2024-01-18 [1] RSPM\n#> tzdb 0.4.0 2023-05-12 [1] RSPM\n#> urlchecker 1.0.1 2021-11-30 [1] RSPM\n#> usethis * 2.2.2 2023-07-06 [1] RSPM\n#> utf8 1.2.4 2023-10-22 [1] RSPM\n#> vctrs 0.6.5 2023-12-01 [1] RSPM\n#> vroom 1.6.5 2023-12-05 [1] RSPM\n#> withr 3.0.0 2024-01-16 [1] RSPM\n#> xfun 0.41 2023-11-01 [1] RSPM\n#> xml2 1.3.6 2023-12-04 [1] RSPM\n#> xtable 1.8-4 2019-04-21 [1] RSPM\n#> \n#> [1] /home/runner/work/_temp/Library\n#> [2] /opt/R/4.3.2/lib/R/site-library\n#> [3] /opt/R/4.3.2/lib/R/library\n#> \n#> ──────────────────────────────────────────────────────────────────\n\n\n\n\n\nMüller, Kirill, and Lorenz Walthert. 2018. Styler: Non-Invasive Pretty Printing of R Code. http://styler.r-lib.org." + "text": "Colophon\nThis book was authored using Quarto inside RStudio. The website is hosted with Netlify, and automatically updated after every commit by GitHub actions. The complete source is available from GitHub.\nThis version of the book was built with:\n\nlibrary(devtools)\n#> Loading required package: usethis\nlibrary(roxygen2)\nlibrary(testthat)\n#> \n#> Attaching package: 'testthat'\n#> The following object is masked from 'package:devtools':\n#> \n#> test_file\n#> The following object is masked from 'package:dplyr':\n#> \n#> matches\n#> The following object is masked from 'package:purrr':\n#> \n#> is_null\n#> The following objects are masked from 'package:readr':\n#> \n#> edition_get, local_edition\n#> The following object is masked from 'package:tidyr':\n#> \n#> matches\ndevtools::session_info()\n#> ─ Session info ───────────────────────────────────────────────────\n#> setting value\n#> version R version 4.3.2 (2023-10-31)\n#> os Ubuntu 22.04.3 LTS\n#> system x86_64, linux-gnu\n#> ui X11\n#> language (EN)\n#> collate C.UTF-8\n#> ctype C.UTF-8\n#> tz UTC\n#> date 2024-01-22\n#> pandoc 2.9.2.1 @ /usr/bin/ (via rmarkdown)\n#> \n#> ─ Packages ───────────────────────────────────────────────────────\n#> package * version date (UTC) lib source\n#> bit 4.0.5 2022-11-15 [1] RSPM\n#> bit64 4.0.5 2020-08-30 [1] RSPM\n#> brio 1.1.4 2023-12-10 [1] RSPM\n#> cachem 1.0.8 2023-05-01 [1] RSPM\n#> cli 3.6.2 2023-12-11 [1] RSPM\n#> colorspace 2.1-0 2023-01-23 [1] RSPM\n#> crayon 1.5.2 2022-09-29 [1] RSPM\n#> devtools * 2.4.5 2022-10-11 [1] RSPM\n#> digest 0.6.34 2024-01-11 [1] RSPM\n#> dplyr * 1.1.4 2023-11-17 [1] RSPM\n#> ellipsis 0.3.2 2021-04-29 [1] RSPM\n#> evaluate 0.23 2023-11-01 [1] RSPM\n#> fansi 1.0.6 2023-12-08 [1] RSPM\n#> fastmap 1.1.1 2023-02-24 [1] RSPM\n#> forcats * 1.0.0 2023-01-29 [1] RSPM\n#> fs 1.6.3 2023-07-20 [1] RSPM\n#> generics 0.1.3 2022-07-05 [1] RSPM\n#> ggplot2 * 3.4.4 2023-10-12 [1] RSPM\n#> glue 1.7.0 2024-01-09 [1] RSPM\n#> gtable 0.3.4 2023-08-21 [1] RSPM\n#> hms 1.1.3 2023-03-21 [1] RSPM\n#> htmltools 0.5.7 2023-11-03 [1] RSPM\n#> htmlwidgets 1.6.4 2023-12-06 [1] RSPM\n#> httpuv 1.6.13 2023-12-06 [1] RSPM\n#> jsonlite 1.8.8 2023-12-04 [1] RSPM\n#> knitr 1.45 2023-10-30 [1] RSPM\n#> later 1.3.2 2023-12-06 [1] RSPM\n#> lifecycle 1.0.4 2023-11-07 [1] RSPM\n#> lubridate * 1.9.3 2023-09-27 [1] RSPM\n#> magrittr 2.0.3 2022-03-30 [1] RSPM\n#> memoise 2.0.1 2021-11-26 [1] RSPM\n#> mime 0.12 2021-09-28 [1] RSPM\n#> miniUI 0.1.1.1 2018-05-18 [1] RSPM\n#> munsell 0.5.0 2018-06-12 [1] RSPM\n#> pillar 1.9.0 2023-03-22 [1] RSPM\n#> pkgbuild 1.4.3 2023-12-10 [1] RSPM\n#> pkgconfig 2.0.3 2019-09-22 [1] RSPM\n#> pkgload 1.3.4 2024-01-16 [1] RSPM\n#> profvis 0.3.8 2023-05-02 [1] RSPM\n#> promises 1.2.1 2023-08-10 [1] RSPM\n#> purrr * 1.0.2 2023-08-10 [1] RSPM\n#> R6 2.5.1 2021-08-19 [1] RSPM\n#> Rcpp 1.0.12 2024-01-09 [1] RSPM\n#> readr * 2.1.5 2024-01-10 [1] RSPM\n#> remotes 2.4.2.1 2023-07-18 [1] RSPM\n#> rlang 1.1.3 2024-01-10 [1] RSPM\n#> rmarkdown 2.25 2023-09-18 [1] RSPM\n#> roxygen2 * 7.3.0 2024-01-11 [1] RSPM\n#> scales 1.3.0 2023-11-28 [1] RSPM\n#> sessioninfo 1.2.2 2021-12-06 [1] RSPM\n#> shiny 1.8.0 2023-11-17 [1] RSPM\n#> stringi 1.8.3 2023-12-11 [1] RSPM\n#> stringr * 1.5.1 2023-11-14 [1] RSPM\n#> testthat * 3.2.1 2023-12-02 [1] RSPM\n#> tibble * 3.2.1 2023-03-20 [1] RSPM\n#> tidyr * 1.3.0 2023-01-24 [1] RSPM\n#> tidyselect 1.2.0 2022-10-10 [1] RSPM\n#> tidyverse * 2.0.0 2023-02-22 [1] RSPM\n#> timechange 0.3.0 2024-01-18 [1] RSPM\n#> tzdb 0.4.0 2023-05-12 [1] RSPM\n#> urlchecker 1.0.1 2021-11-30 [1] RSPM\n#> usethis * 2.2.2 2023-07-06 [1] RSPM\n#> utf8 1.2.4 2023-10-22 [1] RSPM\n#> vctrs 0.6.5 2023-12-01 [1] RSPM\n#> vroom 1.6.5 2023-12-05 [1] RSPM\n#> withr 3.0.0 2024-01-16 [1] RSPM\n#> xfun 0.41 2023-11-01 [1] RSPM\n#> xml2 1.3.6 2023-12-04 [1] RSPM\n#> xtable 1.8-4 2019-04-21 [1] RSPM\n#> \n#> [1] /home/runner/work/_temp/Library\n#> [2] /opt/R/4.3.2/lib/R/site-library\n#> [3] /opt/R/4.3.2/lib/R/library\n#> \n#> ──────────────────────────────────────────────────────────────────\n\n\n\n\n\nMüller, Kirill, and Lorenz Walthert. 2018. Styler: Non-Invasive Pretty Printing of R Code. http://styler.r-lib.org." }, { "objectID": "introduction.html#sec-intro-phil", @@ -81,14 +81,14 @@ "href": "whole-game.html#create_package", "title": "1  The Whole Game", "section": "\n1.4 create_package()\n", - "text": "1.4 create_package()\n\nCall create_package() to initialize a new package in a directory on your computer. create_package() will automatically create that directory if it doesn’t exist yet (and that is usually the case). See Section 4.1 for more on creating packages.\nMake a deliberate choice about where to create this package on your computer. It should probably be somewhere within your home directory, alongside your other R projects. It should not be nested inside another RStudio Project, R package, or Git repo. Nor should it be in an R package library, which holds packages that have already been built and installed. The conversion of the source package we create here into an installed package is part of what devtools facilitates. Don’t try to do devtools’ job for it!\nOnce you’ve selected where to create this package, substitute your chosen path into a create_package() call like this:\n\ncreate_package(\"~/path/to/regexcite\")\n\nFor the creation of this book we have to work in a temporary directory, because the book is built non-interactively in the cloud. Behind the scenes, we’re executing our own create_package() command, but don’t be surprised if our output differs a bit from yours.\n\n#> ✔ Creating '/tmp/RtmpfU7Z6e/regexcite/'\n#> ✔ Setting active project to '/tmp/RtmpfU7Z6e/regexcite'\n#> ✔ Creating 'R/'\n#> ✔ Writing 'DESCRIPTION'\n#> Package: regexcite\n#> Title: What the Package Does (One Line, Title Case)\n#> Version: 0.0.0.9000\n#> Authors@R (parsed):\n#> * First Last <first.last@example.com> [aut, cre] (YOUR-ORCID-ID)\n#> Description: What the package does (one paragraph).\n#> License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a\n#> license\n#> Encoding: UTF-8\n#> Roxygen: list(markdown = TRUE)\n#> RoxygenNote: 7.3.0\n#> ✔ Writing 'NAMESPACE'\n#> ✔ Writing 'regexcite.Rproj'\n#> ✔ Adding '^regexcite\\\\.Rproj$' to '.Rbuildignore'\n#> ✔ Adding '.Rproj.user' to '.gitignore'\n#> ✔ Adding '^\\\\.Rproj\\\\.user$' to '.Rbuildignore'\n#> ✔ Setting active project to '<no active project>'\n\nIf you’re working in RStudio, you should find yourself in a new instance of RStudio, opened into your new regexcite package (and Project). If you somehow need to do this manually, navigate to the directory and double click on regexcite.Rproj. RStudio has special handling for packages and you should now see a Build tab in the same pane as Environment and History.\nYou probably need to call library(devtools) again, because create_package() has probably dropped you into a fresh R session, in your new package.\n\nlibrary(devtools)\n\nWhat’s in this new directory that is also an R package and, probably, an RStudio Project? Here’s a listing (locally, you can consult your Files pane):\n\n\n\n\npath\ntype\n\n\n\n.Rbuildignore\nfile\n\n\n.gitignore\nfile\n\n\nDESCRIPTION\nfile\n\n\nNAMESPACE\nfile\n\n\nR\ndirectory\n\n\nregexcite.Rproj\nfile\n\n\n\n\n\n\n\n\n\n\n\nRStudio\n\n\n\nIn the Files pane, go to More (gear symbol) > Show Hidden Files to toggle the visibility of hidden files (a.k.a. “dotfiles”). A select few are visible all the time, but sometimes you want to see them all.\n\n\n\n\n.Rbuildignore lists files that we need to have around but that should not be included when building the R package from source. If you aren’t using RStudio, create_package() may not create this file (nor .gitignore) at first, since there’s no RStudio-related machinery that needs to be ignored. However, you will likely develop the need for .Rbuildignore at some point, regardless of what editor you are using. It is discussed in more detail in Section 3.3.1.\n\n.Rproj.user, if you have it, is a directory used internally by RStudio.\n\n.gitignore anticipates Git usage and tells Git to ignore some standard, behind-the-scenes files created by R and RStudio. Even if you do not plan to use Git, this is harmless.\n\nDESCRIPTION provides metadata about your package. We edit this shortly and Chapter 9 covers the general topic of the DESCRIPTION file.\n\nNAMESPACE declares the functions your package exports for external use and the external functions your package imports from other packages. At this point, it is empty, except for a comment declaring that this is a file you should not edit by hand.\nThe R/ directory is the “business end” of your package. It will soon contain .R files with function definitions.\n\nregexcite.Rproj is the file that makes this directory an RStudio Project. Even if you don’t use RStudio, this file is harmless. Or you can suppress its creation with create_package(..., rstudio = FALSE). More in Section 4.2." + "text": "1.4 create_package()\n\nCall create_package() to initialize a new package in a directory on your computer. create_package() will automatically create that directory if it doesn’t exist yet (and that is usually the case). See Section 4.1 for more on creating packages.\nMake a deliberate choice about where to create this package on your computer. It should probably be somewhere within your home directory, alongside your other R projects. It should not be nested inside another RStudio Project, R package, or Git repo. Nor should it be in an R package library, which holds packages that have already been built and installed. The conversion of the source package we create here into an installed package is part of what devtools facilitates. Don’t try to do devtools’ job for it!\nOnce you’ve selected where to create this package, substitute your chosen path into a create_package() call like this:\n\ncreate_package(\"~/path/to/regexcite\")\n\nFor the creation of this book we have to work in a temporary directory, because the book is built non-interactively in the cloud. Behind the scenes, we’re executing our own create_package() command, but don’t be surprised if our output differs a bit from yours.\n\n#> ✔ Creating '/tmp/RtmpBET4N9/regexcite/'\n#> ✔ Setting active project to '/tmp/RtmpBET4N9/regexcite'\n#> ✔ Creating 'R/'\n#> ✔ Writing 'DESCRIPTION'\n#> Package: regexcite\n#> Title: What the Package Does (One Line, Title Case)\n#> Version: 0.0.0.9000\n#> Authors@R (parsed):\n#> * First Last <first.last@example.com> [aut, cre] (YOUR-ORCID-ID)\n#> Description: What the package does (one paragraph).\n#> License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a\n#> license\n#> Encoding: UTF-8\n#> Roxygen: list(markdown = TRUE)\n#> RoxygenNote: 7.3.0\n#> ✔ Writing 'NAMESPACE'\n#> ✔ Writing 'regexcite.Rproj'\n#> ✔ Adding '^regexcite\\\\.Rproj$' to '.Rbuildignore'\n#> ✔ Adding '.Rproj.user' to '.gitignore'\n#> ✔ Adding '^\\\\.Rproj\\\\.user$' to '.Rbuildignore'\n#> ✔ Setting active project to '<no active project>'\n\nIf you’re working in RStudio, you should find yourself in a new instance of RStudio, opened into your new regexcite package (and Project). If you somehow need to do this manually, navigate to the directory and double click on regexcite.Rproj. RStudio has special handling for packages and you should now see a Build tab in the same pane as Environment and History.\nYou probably need to call library(devtools) again, because create_package() has probably dropped you into a fresh R session, in your new package.\n\nlibrary(devtools)\n\nWhat’s in this new directory that is also an R package and, probably, an RStudio Project? Here’s a listing (locally, you can consult your Files pane):\n\n\n\n\npath\ntype\n\n\n\n.Rbuildignore\nfile\n\n\n.gitignore\nfile\n\n\nDESCRIPTION\nfile\n\n\nNAMESPACE\nfile\n\n\nR\ndirectory\n\n\nregexcite.Rproj\nfile\n\n\n\n\n\n\n\n\n\n\n\nRStudio\n\n\n\nIn the Files pane, go to More (gear symbol) > Show Hidden Files to toggle the visibility of hidden files (a.k.a. “dotfiles”). A select few are visible all the time, but sometimes you want to see them all.\n\n\n\n\n.Rbuildignore lists files that we need to have around but that should not be included when building the R package from source. If you aren’t using RStudio, create_package() may not create this file (nor .gitignore) at first, since there’s no RStudio-related machinery that needs to be ignored. However, you will likely develop the need for .Rbuildignore at some point, regardless of what editor you are using. It is discussed in more detail in Section 3.3.1.\n\n.Rproj.user, if you have it, is a directory used internally by RStudio.\n\n.gitignore anticipates Git usage and tells Git to ignore some standard, behind-the-scenes files created by R and RStudio. Even if you do not plan to use Git, this is harmless.\n\nDESCRIPTION provides metadata about your package. We edit this shortly and Chapter 9 covers the general topic of the DESCRIPTION file.\n\nNAMESPACE declares the functions your package exports for external use and the external functions your package imports from other packages. At this point, it is empty, except for a comment declaring that this is a file you should not edit by hand.\nThe R/ directory is the “business end” of your package. It will soon contain .R files with function definitions.\n\nregexcite.Rproj is the file that makes this directory an RStudio Project. Even if you don’t use RStudio, this file is harmless. Or you can suppress its creation with create_package(..., rstudio = FALSE). More in Section 4.2." }, { "objectID": "whole-game.html#use_git", "href": "whole-game.html#use_git", "title": "1  The Whole Game", "section": "\n1.5 use_git()\n", - "text": "1.5 use_git()\n\nThe regexcite directory is an R source package and an RStudio Project. Now we make it also a Git repository, with use_git(). (By the way, use_git() works in any project, regardless of whether it’s an R package.)\n\nuse_git()\n#> ✔ Initialising Git repo\n#> ✔ Adding '.Rhistory', '.Rdata', '.httr-oauth', '.DS_Store', '.quarto' to '.gitignore'\n\nIn an interactive session, you will be asked if you want to commit some files here and you should accept the offer. Behind the scenes, we’ll also commit those same files.\nSo what has changed in the package? Only the creation of a .git directory, which is hidden in most contexts, including the RStudio file browser. Its existence is evidence that we have indeed initialized a Git repo here.\n\n\n\n\npath\ntype\n\n\n.git\ndirectory\n\n\n\n\nIf you’re using RStudio, it probably requested permission to relaunch itself in this Project, which you should do. You can do so manually by quitting, then relaunching RStudio by double clicking on regexcite.Rproj. Now, in addition to package development support, you have access to a basic Git client in the Git tab of the Environment/History/Build pane.\n\nClick on History (the clock icon in the Git pane) and, if you consented, you will see an initial commit made via use_git():\n\n\n\n\ncommit\nauthor\nmessage\n\n\n502b140b45…\njennybc jennybc@users.noreply.github.com\n\nInitial commit\n\n\n\n\n\n\n\n\n\n\nRStudio\n\n\n\nRStudio can initialize a Git repository, in any Project, even if it’s not an R package, as long you’ve set up RStudio + Git integration. Do Tools > Version Control > Project Setup. Then choose Version control system: Git and initialize a new git repository for this project." + "text": "1.5 use_git()\n\nThe regexcite directory is an R source package and an RStudio Project. Now we make it also a Git repository, with use_git(). (By the way, use_git() works in any project, regardless of whether it’s an R package.)\n\nuse_git()\n#> ✔ Initialising Git repo\n#> ✔ Adding '.Rhistory', '.Rdata', '.httr-oauth', '.DS_Store', '.quarto' to '.gitignore'\n\nIn an interactive session, you will be asked if you want to commit some files here and you should accept the offer. Behind the scenes, we’ll also commit those same files.\nSo what has changed in the package? Only the creation of a .git directory, which is hidden in most contexts, including the RStudio file browser. Its existence is evidence that we have indeed initialized a Git repo here.\n\n\n\n\npath\ntype\n\n\n.git\ndirectory\n\n\n\n\nIf you’re using RStudio, it probably requested permission to relaunch itself in this Project, which you should do. You can do so manually by quitting, then relaunching RStudio by double clicking on regexcite.Rproj. Now, in addition to package development support, you have access to a basic Git client in the Git tab of the Environment/History/Build pane.\n\nClick on History (the clock icon in the Git pane) and, if you consented, you will see an initial commit made via use_git():\n\n\n\n\ncommit\nauthor\nmessage\n\n\n0c2fae2443…\njennybc jennybc@users.noreply.github.com\n\nInitial commit\n\n\n\n\n\n\n\n\n\n\nRStudio\n\n\n\nRStudio can initialize a Git repository, in any Project, even if it’s not an R package, as long you’ve set up RStudio + Git integration. Do Tools > Version Control > Project Setup. Then choose Version control system: Git and initialize a new git repository for this project." }, { "objectID": "whole-game.html#write-the-first-function", @@ -116,7 +116,7 @@ "href": "whole-game.html#check", "title": "1  The Whole Game", "section": "\n1.9 check()\n", - "text": "1.9 check()\n\nWe have informal, empirical evidence that strsplit1() works. But how can we be sure that all the moving parts of the regexcite package still work? This may seem silly to check, after such a small addition, but it’s good to establish the habit of checking this often.\nR CMD check, executed in the shell, is the gold standard for checking that an R package is in full working order. check() is a convenient way to run this without leaving your R session.\nNote that check() produces rather voluminous output, optimized for interactive consumption. We intercept that here and just reveal a summary. Your local check() output will be different.\n\ncheck()\n\n\n── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────\nDuration: 7.2s\n\n❯ checking DESCRIPTION meta-information ... WARNING\n Non-standard license specification:\n `use_mit_license()`, `use_gpl3_license()` or friends to pick a\n license\n Standardizable: FALSE\n\n0 errors ✔ | 1 warning ✖ | 0 notes ✔\n\nIt is essential to actually read the output of the check! Deal with problems early and often. It’s just like incremental development of .R and .Rmd files. The longer you go between full checks that everything works, the harder it becomes to pinpoint and solve your problems.\nAt this point, we expect 1 warning (and 0 errors, 0 notes):\nNon-standard license specification:\n `use_mit_license()`, `use_gpl3_license()` or friends to pick a\n license\nWe’ll address that soon, by doing exactly what it says. You can learn more about check() in Section 4.5.\n\n\n\n\n\n\nRStudio\n\n\n\nRStudio exposes check() in the Build menu, in the Build pane via Check, and in keyboard shortcuts Ctrl + Shift + E (Windows & Linux) or Cmd + Shift + E (macOS)." + "text": "1.9 check()\n\nWe have informal, empirical evidence that strsplit1() works. But how can we be sure that all the moving parts of the regexcite package still work? This may seem silly to check, after such a small addition, but it’s good to establish the habit of checking this often.\nR CMD check, executed in the shell, is the gold standard for checking that an R package is in full working order. check() is a convenient way to run this without leaving your R session.\nNote that check() produces rather voluminous output, optimized for interactive consumption. We intercept that here and just reveal a summary. Your local check() output will be different.\n\ncheck()\n\n\n── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────\nDuration: 6.6s\n\n❯ checking DESCRIPTION meta-information ... WARNING\n Non-standard license specification:\n `use_mit_license()`, `use_gpl3_license()` or friends to pick a\n license\n Standardizable: FALSE\n\n0 errors ✔ | 1 warning ✖ | 0 notes ✔\n\nIt is essential to actually read the output of the check! Deal with problems early and often. It’s just like incremental development of .R and .Rmd files. The longer you go between full checks that everything works, the harder it becomes to pinpoint and solve your problems.\nAt this point, we expect 1 warning (and 0 errors, 0 notes):\nNon-standard license specification:\n `use_mit_license()`, `use_gpl3_license()` or friends to pick a\n license\nWe’ll address that soon, by doing exactly what it says. You can learn more about check() in Section 4.5.\n\n\n\n\n\n\nRStudio\n\n\n\nRStudio exposes check() in the Build menu, in the Build pane via Check, and in keyboard shortcuts Ctrl + Shift + E (Windows & Linux) or Cmd + Shift + E (macOS)." }, { "objectID": "whole-game.html#edit-description", @@ -144,14 +144,14 @@ "href": "whole-game.html#check-again", "title": "1  The Whole Game", "section": "\n1.13 check() again", - "text": "1.13 check() again\nregexcite should pass R CMD check cleanly now and forever more: 0 errors, 0 warnings, 0 notes.\n\ncheck()\n\n\n── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────\nDuration: 8.9s\n\n0 errors ✔ | 0 warnings ✔ | 0 notes ✔" + "text": "1.13 check() again\nregexcite should pass R CMD check cleanly now and forever more: 0 errors, 0 warnings, 0 notes.\n\ncheck()\n\n\n── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────\nDuration: 8s\n\n0 errors ✔ | 0 warnings ✔ | 0 notes ✔" }, { "objectID": "whole-game.html#install", "href": "whole-game.html#install", "title": "1  The Whole Game", "section": "\n1.14 install()\n", - "text": "1.14 install()\n\nNow that we know we have a minimum viable product, let’s install the regexcite package into your library via install():\n\ninstall()\n\n\n── R CMD build ─────────────────────────────────────────────────────\n* checking for file ‘/tmp/RtmpfU7Z6e/regexcite/DESCRIPTION’ ... OK\n* preparing ‘regexcite’:\n* checking DESCRIPTION meta-information ... OK\n* checking for LF line-endings in source and make files and shell scripts\n* checking for empty or unneeded directories\n* building ‘regexcite_0.0.0.9000.tar.gz’\nRunning /opt/R/4.3.2/lib/R/bin/R CMD INSTALL \\\n /tmp/RtmpfU7Z6e/regexcite_0.0.0.9000.tar.gz --install-tests \n* installing to library ‘/home/runner/work/_temp/Library’\n* installing *source* package ‘regexcite’ ...\n** using staged installation\n** R\n** byte-compile and prepare package for lazy loading\n** help\n*** installing help indices\n** building package indices\n** testing if installed package can be loaded from temporary location\n** testing if installed package can be loaded from final location\n** testing if installed package keeps a record of temporary installation path\n* DONE (regexcite)\n\n\n\n\n\n\n\nRStudio\n\n\n\nRStudio exposes similar functionality in the Build menu and in the Build pane via Install and Restart, and in keyboard shortcuts Ctrl + Shift + B (Windows & Linux) or Cmd + Shift + B (macOS).\n\n\nAfter installation is complete, we can attach and use regexcite like any other package. Let’s revisit our small example from the top. This is also a good time to restart your R session and ensure you have a clean workspace.\n\nlibrary(regexcite)\n\nx <- \"alfa,bravo,charlie,delta\"\nstrsplit1(x, split = \",\")\n#> [1] \"alfa\" \"bravo\" \"charlie\" \"delta\"\n\nSuccess!" + "text": "1.14 install()\n\nNow that we know we have a minimum viable product, let’s install the regexcite package into your library via install():\n\ninstall()\n\n\n── R CMD build ─────────────────────────────────────────────────────\n* checking for file ‘/tmp/RtmpBET4N9/regexcite/DESCRIPTION’ ... OK\n* preparing ‘regexcite’:\n* checking DESCRIPTION meta-information ... OK\n* checking for LF line-endings in source and make files and shell scripts\n* checking for empty or unneeded directories\n* building ‘regexcite_0.0.0.9000.tar.gz’\nRunning /opt/R/4.3.2/lib/R/bin/R CMD INSTALL \\\n /tmp/RtmpBET4N9/regexcite_0.0.0.9000.tar.gz --install-tests \n* installing to library ‘/home/runner/work/_temp/Library’\n* installing *source* package ‘regexcite’ ...\n** using staged installation\n** R\n** byte-compile and prepare package for lazy loading\n** help\n*** installing help indices\n** building package indices\n** testing if installed package can be loaded from temporary location\n** testing if installed package can be loaded from final location\n** testing if installed package keeps a record of temporary installation path\n* DONE (regexcite)\n\n\n\n\n\n\n\nRStudio\n\n\n\nRStudio exposes similar functionality in the Build menu and in the Build pane via Install and Restart, and in keyboard shortcuts Ctrl + Shift + B (Windows & Linux) or Cmd + Shift + B (macOS).\n\n\nAfter installation is complete, we can attach and use regexcite like any other package. Let’s revisit our small example from the top. This is also a good time to restart your R session and ensure you have a clean workspace.\n\nlibrary(regexcite)\n\nx <- \"alfa,bravo,charlie,delta\"\nstrsplit1(x, split = \",\")\n#> [1] \"alfa\" \"bravo\" \"charlie\" \"delta\"\n\nSuccess!" }, { "objectID": "whole-game.html#use_testthat", @@ -179,14 +179,14 @@ "href": "whole-game.html#use_readme_rmd", "title": "1  The Whole Game", "section": "\n1.18 use_readme_rmd()\n", - "text": "1.18 use_readme_rmd()\n\nNow that your package is on GitHub, the README.md file matters. It is the package’s home page and welcome mat, at least until you decide to give it a website (see Chapter 19), add a vignette (see Chapter 17), or submit it to CRAN (see Chapter 22).\nThe use_readme_rmd() function initializes a basic, executable README.Rmd ready for you to edit:\n\nuse_readme_rmd()\n#> ✔ Writing 'README.Rmd'\n#> ✔ Adding '^README\\\\.Rmd$' to '.Rbuildignore'\n#> • Update 'README.Rmd' to include installation instructions.\n#> ✔ Writing '.git/hooks/pre-commit'\n\nIn addition to creating README.Rmd, this adds some lines to .Rbuildignore, and creates a Git pre-commit hook to help you keep README.Rmd and README.md in sync.\nREADME.Rmd already has sections that prompt you to:\n\nDescribe the purpose of the package.\nProvide installation instructions. If a GitHub remote is detected when use_readme_rmd() is called, this section is pre-filled with instructions on how to install from GitHub.\nShow a bit of usage.\n\nHow to populate this skeleton? Copy stuff liberally from DESCRIPTION and any formal and informal tests or examples you have. Anything is better than nothing. This is helpful because people probably won’t install your package and comb through individual help files to figure out how to use it.\nWe like to write the README in R Markdown, so it can feature actual usage. The inclusion of live code also makes it less likely that your README grows stale and out-of-sync with your actual package.\nTo make your own edits, if RStudio has not already done so, open README.Rmd for editing. Make sure it shows some usage of str_split_one().\nThe README.Rmd we use is here: README.Rmd and here’s what it contains:\n\n---\noutput: github_document\n---\n\n<!-- README.md is generated from README.Rmd. Please edit that file -->\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n collapse = TRUE,\n comment = \"#>\",\n fig.path = \"man/figures/README-\",\n out.width = \"100%\"\n)\n```\n\n**NOTE: This is a toy package created for expository purposes, for the second edition of [R Packages](https://r-pkgs.org). It is not meant to actually be useful. If you want a package for factor handling, please see [stringr](https://stringr.tidyverse.org), [stringi](https://stringi.gagolewski.com/),\n[rex](https://cran.r-project.org/package=rex), and\n[rematch2](https://cran.r-project.org/package=rematch2).**\n\n# regexcite\n\n<!-- badges: start -->\n<!-- badges: end -->\n\nThe goal of regexcite is to make regular expressions more exciting!\nIt provides convenience functions to make some common tasks with string manipulation and regular expressions a bit easier.\n\n## Installation\n\nYou can install the development version of regexcite from [GitHub](https://github.com/) with:\n \n``` r\n# install.packages(\"devtools\")\ndevtools::install_github(\"jennybc/regexcite\")\n```\n\n## Usage\n\nA fairly common task when dealing with strings is the need to split a single string into many parts.\nThis is what `base::strplit()` and `stringr::str_split()` do.\n\n```{r}\n(x <- \"alfa,bravo,charlie,delta\")\nstrsplit(x, split = \",\")\nstringr::str_split(x, pattern = \",\")\n```\n\nNotice how the return value is a **list** of length one, where the first element holds the character vector of parts.\nOften the shape of this output is inconvenient, i.e. we want the un-listed version.\n\nThat's exactly what `regexcite::str_split_one()` does.\n\n```{r}\nlibrary(regexcite)\n\nstr_split_one(x, pattern = \",\")\n```\n\nUse `str_split_one()` when the input is known to be a single string.\nFor safety, it will error if its input has length greater than one.\n\n`str_split_one()` is built on `stringr::str_split()`, so you can use its `n` argument and stringr's general interface for describing the `pattern` to be matched.\n\n```{r}\nstr_split_one(x, pattern = \",\", n = 2)\n\ny <- \"192.168.0.1\"\nstr_split_one(y, pattern = stringr::fixed(\".\"))\n```\n\nDon’t forget to render it to make README.md! The pre-commit hook should remind you if you try to commit README.Rmd, but not README.md, and also when README.md appears to be out-of-date.\nThe very best way to render README.Rmd is with build_readme(), because it takes care to render with the most current version of your package, i.e. it installs a temporary copy from the current source.\n\nbuild_readme()\n#> ℹ Installing regexcite in temporary library\n#> ℹ Building '/tmp/RtmpfU7Z6e/regexcite/README.Rmd'\n\nYou can see the rendered README.md simply by visiting regexcite on GitHub.\nFinally, don’t forget to do one last commit. And push, if you’re using GitHub." + "text": "1.18 use_readme_rmd()\n\nNow that your package is on GitHub, the README.md file matters. It is the package’s home page and welcome mat, at least until you decide to give it a website (see Chapter 19), add a vignette (see Chapter 17), or submit it to CRAN (see Chapter 22).\nThe use_readme_rmd() function initializes a basic, executable README.Rmd ready for you to edit:\n\nuse_readme_rmd()\n#> ✔ Writing 'README.Rmd'\n#> ✔ Adding '^README\\\\.Rmd$' to '.Rbuildignore'\n#> • Update 'README.Rmd' to include installation instructions.\n#> ✔ Writing '.git/hooks/pre-commit'\n\nIn addition to creating README.Rmd, this adds some lines to .Rbuildignore, and creates a Git pre-commit hook to help you keep README.Rmd and README.md in sync.\nREADME.Rmd already has sections that prompt you to:\n\nDescribe the purpose of the package.\nProvide installation instructions. If a GitHub remote is detected when use_readme_rmd() is called, this section is pre-filled with instructions on how to install from GitHub.\nShow a bit of usage.\n\nHow to populate this skeleton? Copy stuff liberally from DESCRIPTION and any formal and informal tests or examples you have. Anything is better than nothing. This is helpful because people probably won’t install your package and comb through individual help files to figure out how to use it.\nWe like to write the README in R Markdown, so it can feature actual usage. The inclusion of live code also makes it less likely that your README grows stale and out-of-sync with your actual package.\nTo make your own edits, if RStudio has not already done so, open README.Rmd for editing. Make sure it shows some usage of str_split_one().\nThe README.Rmd we use is here: README.Rmd and here’s what it contains:\n\n---\noutput: github_document\n---\n\n<!-- README.md is generated from README.Rmd. Please edit that file -->\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n collapse = TRUE,\n comment = \"#>\",\n fig.path = \"man/figures/README-\",\n out.width = \"100%\"\n)\n```\n\n**NOTE: This is a toy package created for expository purposes, for the second edition of [R Packages](https://r-pkgs.org). It is not meant to actually be useful. If you want a package for factor handling, please see [stringr](https://stringr.tidyverse.org), [stringi](https://stringi.gagolewski.com/),\n[rex](https://cran.r-project.org/package=rex), and\n[rematch2](https://cran.r-project.org/package=rematch2).**\n\n# regexcite\n\n<!-- badges: start -->\n<!-- badges: end -->\n\nThe goal of regexcite is to make regular expressions more exciting!\nIt provides convenience functions to make some common tasks with string manipulation and regular expressions a bit easier.\n\n## Installation\n\nYou can install the development version of regexcite from [GitHub](https://github.com/) with:\n \n``` r\n# install.packages(\"devtools\")\ndevtools::install_github(\"jennybc/regexcite\")\n```\n\n## Usage\n\nA fairly common task when dealing with strings is the need to split a single string into many parts.\nThis is what `base::strplit()` and `stringr::str_split()` do.\n\n```{r}\n(x <- \"alfa,bravo,charlie,delta\")\nstrsplit(x, split = \",\")\nstringr::str_split(x, pattern = \",\")\n```\n\nNotice how the return value is a **list** of length one, where the first element holds the character vector of parts.\nOften the shape of this output is inconvenient, i.e. we want the un-listed version.\n\nThat's exactly what `regexcite::str_split_one()` does.\n\n```{r}\nlibrary(regexcite)\n\nstr_split_one(x, pattern = \",\")\n```\n\nUse `str_split_one()` when the input is known to be a single string.\nFor safety, it will error if its input has length greater than one.\n\n`str_split_one()` is built on `stringr::str_split()`, so you can use its `n` argument and stringr's general interface for describing the `pattern` to be matched.\n\n```{r}\nstr_split_one(x, pattern = \",\", n = 2)\n\ny <- \"192.168.0.1\"\nstr_split_one(y, pattern = stringr::fixed(\".\"))\n```\n\nDon’t forget to render it to make README.md! The pre-commit hook should remind you if you try to commit README.Rmd, but not README.md, and also when README.md appears to be out-of-date.\nThe very best way to render README.Rmd is with build_readme(), because it takes care to render with the most current version of your package, i.e. it installs a temporary copy from the current source.\n\nbuild_readme()\n#> ℹ Installing regexcite in temporary library\n#> ℹ Building '/tmp/RtmpBET4N9/regexcite/README.Rmd'\n\nYou can see the rendered README.md simply by visiting regexcite on GitHub.\nFinally, don’t forget to do one last commit. And push, if you’re using GitHub." }, { "objectID": "whole-game.html#the-end-check-and-install", "href": "whole-game.html#the-end-check-and-install", "title": "1  The Whole Game", "section": "\n1.19 The end: check() and install()\n", - "text": "1.19 The end: check() and install()\n\nLet’s run check() again to make sure all is still well.\n\ncheck()\n\n\n── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────\nDuration: 10.1s\n\n0 errors ✔ | 0 warnings ✔ | 0 notes ✔\n\nregexcite should have no errors, warnings or notes. This would be a good time to re-build and install it properly. And celebrate!\n\ninstall()\n\n\n── R CMD build ─────────────────────────────────────────────────────\n* checking for file ‘/tmp/RtmpfU7Z6e/regexcite/DESCRIPTION’ ... OK\n* preparing ‘regexcite’:\n* checking DESCRIPTION meta-information ... OK\n* checking for LF line-endings in source and make files and shell scripts\n* checking for empty or unneeded directories\nRemoved empty directory ‘regexcite/tests/testthat/_snaps’\n* building ‘regexcite_0.0.0.9000.tar.gz’\nRunning /opt/R/4.3.2/lib/R/bin/R CMD INSTALL \\\n /tmp/RtmpfU7Z6e/regexcite_0.0.0.9000.tar.gz --install-tests \n* installing to library ‘/home/runner/work/_temp/Library’\n* installing *source* package ‘regexcite’ ...\n** using staged installation\n** R\n** tests\n** byte-compile and prepare package for lazy loading\n** help\n*** installing help indices\n** building package indices\n** testing if installed package can be loaded from temporary location\n** testing if installed package can be loaded from final location\n** testing if installed package keeps a record of temporary installation path\n* DONE (regexcite)\n\nFeel free to visit the regexcite package on GitHub, which appears exactly as developed here. The commit history reflects each individual step, so use the diffs to see the addition and modification of files, as the package evolved. The rest of this book goes in greater detail for each step you’ve seen here and much more." + "text": "1.19 The end: check() and install()\n\nLet’s run check() again to make sure all is still well.\n\ncheck()\n\n\n── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────\nDuration: 9.2s\n\n0 errors ✔ | 0 warnings ✔ | 0 notes ✔\n\nregexcite should have no errors, warnings or notes. This would be a good time to re-build and install it properly. And celebrate!\n\ninstall()\n\n\n── R CMD build ─────────────────────────────────────────────────────\n* checking for file ‘/tmp/RtmpBET4N9/regexcite/DESCRIPTION’ ... OK\n* preparing ‘regexcite’:\n* checking DESCRIPTION meta-information ... OK\n* checking for LF line-endings in source and make files and shell scripts\n* checking for empty or unneeded directories\nRemoved empty directory ‘regexcite/tests/testthat/_snaps’\n* building ‘regexcite_0.0.0.9000.tar.gz’\nRunning /opt/R/4.3.2/lib/R/bin/R CMD INSTALL \\\n /tmp/RtmpBET4N9/regexcite_0.0.0.9000.tar.gz --install-tests \n* installing to library ‘/home/runner/work/_temp/Library’\n* installing *source* package ‘regexcite’ ...\n** using staged installation\n** R\n** tests\n** byte-compile and prepare package for lazy loading\n** help\n*** installing help indices\n** building package indices\n** testing if installed package can be loaded from temporary location\n** testing if installed package can be loaded from final location\n** testing if installed package keeps a record of temporary installation path\n* DONE (regexcite)\n\nFeel free to visit the regexcite package on GitHub, which appears exactly as developed here. The commit history reflects each individual step, so use the diffs to see the addition and modification of files, as the package evolved. The rest of this book goes in greater detail for each step you’ve seen here and much more." }, { "objectID": "whole-game.html#review", @@ -340,7 +340,7 @@ "href": "package-within.html#alfa-a-script-that-works", "title": "5  The package within", "section": "\n5.1 Alfa: a script that works", - "text": "5.1 Alfa: a script that works\n\nLet’s consider data-cleaning.R, a fictional data analysis script for a group that collects reports from people who went for a swim:\n\nWhere did you swim and how hot was it outside?\n\nTheir data usually comes as a CSV file, such as swim.csv:\n\nname,where,temp\nAdam,beach,95\nBess,coast,91\nCora,seashore,28\nDale,beach,85\nEvan,seaside,31\n\ndata-cleaning.R begins by reading swim.csv into a data frame:\n\ninfile <- \"swim.csv\"\n(dat <- read.csv(infile))\n\n\n#> name where temp\n#> 1 Adam beach 95\n#> 2 Bess coast 91\n#> 3 Cora seashore 28\n#> 4 Dale beach 85\n#> 5 Evan seaside 31\n\nThey then classify each observation as using American (“US”) or British (“UK”) English, based on the word chosen to describe the sandy place where the ocean and land meet. The where column is used to build the new english column.\n\ndat$english[dat$where == \"beach\"] <- \"US\"\ndat$english[dat$where == \"coast\"] <- \"US\"\ndat$english[dat$where == \"seashore\"] <- \"UK\"\ndat$english[dat$where == \"seaside\"] <- \"UK\"\n\nSadly, the temperatures are often reported in a mix of Fahrenheit and Celsius. In the absence of better information, they guess that Americans report temperatures in Fahrenheit and therefore those observations are converted to Celsius.\n\ndat$temp[dat$english == \"US\"] <- (dat$temp[dat$english == \"US\"] - 32) * 5/9\ndat\n#> name where temp english\n#> 1 Adam beach 35.0 US\n#> 2 Bess coast 32.8 US\n#> 3 Cora seashore 28.0 UK\n#> 4 Dale beach 29.4 US\n#> 5 Evan seaside 31.0 UK\n\nFinally, this cleaned (cleaner?) data is written back out to a CSV file. They like to capture a timestamp in the filename when they do this1.\n\nnow <- Sys.time()\ntimestamp <- format(now, \"%Y-%B-%d_%H-%M-%S\")\n(outfile <- paste0(timestamp, \"_\", sub(\"(.*)([.]csv$)\", \"\\\\1_clean\\\\2\", infile)))\n#> [1] \"2024-January-21_07-14-26_swim_clean.csv\"\nwrite.csv(dat, file = outfile, quote = FALSE, row.names = FALSE)\n\nHere is data-cleaning.R in its entirety:\n\n\ninfile <- \"swim.csv\"\n(dat <- read.csv(infile))\n\ndat$english[dat$where == \"beach\"] <- \"US\"\ndat$english[dat$where == \"coast\"] <- \"US\"\ndat$english[dat$where == \"seashore\"] <- \"UK\"\ndat$english[dat$where == \"seaside\"] <- \"UK\"\n\ndat$temp[dat$english == \"US\"] <- (dat$temp[dat$english == \"US\"] - 32) * 5/9\ndat\n\nnow <- Sys.time()\ntimestamp <- format(now, \"%Y-%B-%d_%H-%M-%S\")\n(outfile <- paste0(timestamp, \"_\", sub(\"(.*)([.]csv$)\", \"\\\\1_clean\\\\2\", infile)))\nwrite.csv(dat, file = outfile, quote = FALSE, row.names = FALSE)\n\nEven if your typical analytical tasks are quite different, hopefully you see a few familiar patterns here. It’s easy to imagine that this group does very similar pre-processing of many similar data files over time. Their analyses can be more efficient and consistent if they make these standard data maneuvers available to themselves as functions in a package, instead of inlining the same data and logic into dozens or hundreds of data ingest scripts." + "text": "5.1 Alfa: a script that works\n\nLet’s consider data-cleaning.R, a fictional data analysis script for a group that collects reports from people who went for a swim:\n\nWhere did you swim and how hot was it outside?\n\nTheir data usually comes as a CSV file, such as swim.csv:\n\nname,where,temp\nAdam,beach,95\nBess,coast,91\nCora,seashore,28\nDale,beach,85\nEvan,seaside,31\n\ndata-cleaning.R begins by reading swim.csv into a data frame:\n\ninfile <- \"swim.csv\"\n(dat <- read.csv(infile))\n\n\n#> name where temp\n#> 1 Adam beach 95\n#> 2 Bess coast 91\n#> 3 Cora seashore 28\n#> 4 Dale beach 85\n#> 5 Evan seaside 31\n\nThey then classify each observation as using American (“US”) or British (“UK”) English, based on the word chosen to describe the sandy place where the ocean and land meet. The where column is used to build the new english column.\n\ndat$english[dat$where == \"beach\"] <- \"US\"\ndat$english[dat$where == \"coast\"] <- \"US\"\ndat$english[dat$where == \"seashore\"] <- \"UK\"\ndat$english[dat$where == \"seaside\"] <- \"UK\"\n\nSadly, the temperatures are often reported in a mix of Fahrenheit and Celsius. In the absence of better information, they guess that Americans report temperatures in Fahrenheit and therefore those observations are converted to Celsius.\n\ndat$temp[dat$english == \"US\"] <- (dat$temp[dat$english == \"US\"] - 32) * 5/9\ndat\n#> name where temp english\n#> 1 Adam beach 35.0 US\n#> 2 Bess coast 32.8 US\n#> 3 Cora seashore 28.0 UK\n#> 4 Dale beach 29.4 US\n#> 5 Evan seaside 31.0 UK\n\nFinally, this cleaned (cleaner?) data is written back out to a CSV file. They like to capture a timestamp in the filename when they do this1.\n\nnow <- Sys.time()\ntimestamp <- format(now, \"%Y-%B-%d_%H-%M-%S\")\n(outfile <- paste0(timestamp, \"_\", sub(\"(.*)([.]csv$)\", \"\\\\1_clean\\\\2\", infile)))\n#> [1] \"2024-January-22_07-14-10_swim_clean.csv\"\nwrite.csv(dat, file = outfile, quote = FALSE, row.names = FALSE)\n\nHere is data-cleaning.R in its entirety:\n\n\ninfile <- \"swim.csv\"\n(dat <- read.csv(infile))\n\ndat$english[dat$where == \"beach\"] <- \"US\"\ndat$english[dat$where == \"coast\"] <- \"US\"\ndat$english[dat$where == \"seashore\"] <- \"UK\"\ndat$english[dat$where == \"seaside\"] <- \"UK\"\n\ndat$temp[dat$english == \"US\"] <- (dat$temp[dat$english == \"US\"] - 32) * 5/9\ndat\n\nnow <- Sys.time()\ntimestamp <- format(now, \"%Y-%B-%d_%H-%M-%S\")\n(outfile <- paste0(timestamp, \"_\", sub(\"(.*)([.]csv$)\", \"\\\\1_clean\\\\2\", infile)))\nwrite.csv(dat, file = outfile, quote = FALSE, row.names = FALSE)\n\nEven if your typical analytical tasks are quite different, hopefully you see a few familiar patterns here. It’s easy to imagine that this group does very similar pre-processing of many similar data files over time. Their analyses can be more efficient and consistent if they make these standard data maneuvers available to themselves as functions in a package, instead of inlining the same data and logic into dozens or hundreds of data ingest scripts." }, { "objectID": "package-within.html#bravo-a-better-script-that-works", @@ -382,7 +382,7 @@ "href": "package-within.html#sec-package-within-side-effects", "title": "5  The package within", "section": "\n5.7 Golf: side effects", - "text": "5.7 Golf: side effects\nThe timestamps now reflect the current time, but the group raises a new concern. As it stands, the timestamps reflect who has done the data cleaning and which part of the world they’re in. The heart of the timestamp strategy is this format string5:\n\nformat(Sys.time(), \"%Y-%B-%d_%H-%M-%S\")\n#> [1] \"2024-January-21_07-14-26\"\n\nThis formats Sys.time() in such a way that it includes the month name (not number) and the local time6.\nTable 5.1 shows what happens when such a timestamp is produced by several hypothetical colleagues cleaning some data at exactly the same instant in time.\n\n\n\n\nTable 5.1: Timestamp varies by locale and timezone.\n\n\n\n\n\n\n\nlocation\ntimestamp\nLC_TIME\ntz\n\n\n\nRome, Italy\n2020-settembre-05_00-30-00\nit_IT.UTF-8\nEurope/Rome\n\n\nWarsaw, Poland\n2020-września-05_00-30-00\npl_PL.UTF-8\nEurope/Warsaw\n\n\nSao Paulo, Brazil\n2020-setembro-04_19-30-00\npt_BR.UTF-8\nAmerica/Sao_Paulo\n\n\nGreenwich, England\n2020-September-04_23-30-00\nen_GB.UTF-8\nEurope/London\n\n\n“Computer World!”\n2020-September-04_22-30-00\nC\nUTC\n\n\n\n\n\n\nNote that the month names vary, as does the time, and even the date! The safest choice is to form timestamps with respect to a fixed locale and time zone (presumably the non-geographic choices represented by “Computer World!” above).\nYou do some research and learn that you can force a certain locale via Sys.setlocale() and force a certain time zone by setting the TZ environment variable. Specifically, we set the LC_TIME component of the locale to “C” and the time zone to “UTC” (Coordinated Universal Time). Here’s your first attempt to improve timestamp():\n\ntimestamp <- function(time = Sys.time()) {\n Sys.setlocale(\"LC_TIME\", \"C\")\n Sys.setenv(TZ = \"UTC\")\n format(time, \"%Y-%B-%d_%H-%M-%S\")\n}\n\nBut your Brazilian colleague notices that datetimes print differently, before and after she uses outfile_path() from your package:\nBefore:\n\nformat(Sys.time(), \"%Y-%B-%d_%H-%M-%S\")\n\n\n#> [1] \"2024-janeiro-21_04-14-27\"\n\nAfter:\n\noutfile_path(\"INFILE.csv\")\n#> [1] \"2024-January-21_07-14-26_INFILE_clean.csv\"\n\nformat(Sys.time(), \"%Y-%B-%d_%H-%M-%S\")\n#> [1] \"2024-January-21_07-14-27\"\n\nNotice that her month name switched from Portuguese to English and the time is clearly being reported in a different time zone. The calls to Sys.setlocale() and Sys.setenv() inside timestamp() have made persistent (and very surprising) changes to her R session. This sort of side effect is very undesirable and is extremely difficult to track down and debug, especially in more complicated settings.\nHere are better versions of timestamp():\n\n# use withr::local_*() functions to keep the changes local to timestamp()\ntimestamp <- function(time = Sys.time()) {\n withr::local_locale(c(\"LC_TIME\" = \"C\"))\n withr::local_timezone(\"UTC\")\n format(time, \"%Y-%B-%d_%H-%M-%S\")\n}\n\n# use the tz argument to format.POSIXct()\ntimestamp <- function(time = Sys.time()) {\n withr::local_locale(c(\"LC_TIME\" = \"C\"))\n format(time, \"%Y-%B-%d_%H-%M-%S\", tz = \"UTC\")\n}\n\n# put the format() call inside withr::with_*()\ntimestamp <- function(time = Sys.time()) {\n withr::with_locale(\n c(\"LC_TIME\" = \"C\"),\n format(time, \"%Y-%B-%d_%H-%M-%S\", tz = \"UTC\")\n )\n}\n\nThese show various methods to limit the scope of our changes to LC_TIME and the timezone. A good rule of thumb is to make the scope of such changes as narrow as possible and practical. The tz argument of format() is the most surgical way to deal with the timezone, but nothing similar exists for LC_TIME. We make the temporary locale modification using the withr package, which provides a very flexible toolkit for temporary state changes. This (and base::on.exit()) are discussed further in Section 6.5. Note that if you use withr as we do above, you would need to list it in DESCRIPTION in Imports (Chapter 11, Section 10.1.3).\nThis underscores a point from the previous section: you need to adopt a different mindset when defining functions inside a package. Try to avoid making any changes to the user’s overall state. If such changes are unavoidable, make sure to reverse them (if possible) or to document them explicitly (if related to the function’s primary purpose)." + "text": "5.7 Golf: side effects\nThe timestamps now reflect the current time, but the group raises a new concern. As it stands, the timestamps reflect who has done the data cleaning and which part of the world they’re in. The heart of the timestamp strategy is this format string5:\n\nformat(Sys.time(), \"%Y-%B-%d_%H-%M-%S\")\n#> [1] \"2024-January-22_07-14-10\"\n\nThis formats Sys.time() in such a way that it includes the month name (not number) and the local time6.\nTable 5.1 shows what happens when such a timestamp is produced by several hypothetical colleagues cleaning some data at exactly the same instant in time.\n\n\n\n\nTable 5.1: Timestamp varies by locale and timezone.\n\n\n\n\n\n\n\nlocation\ntimestamp\nLC_TIME\ntz\n\n\n\nRome, Italy\n2020-settembre-05_00-30-00\nit_IT.UTF-8\nEurope/Rome\n\n\nWarsaw, Poland\n2020-września-05_00-30-00\npl_PL.UTF-8\nEurope/Warsaw\n\n\nSao Paulo, Brazil\n2020-setembro-04_19-30-00\npt_BR.UTF-8\nAmerica/Sao_Paulo\n\n\nGreenwich, England\n2020-September-04_23-30-00\nen_GB.UTF-8\nEurope/London\n\n\n“Computer World!”\n2020-September-04_22-30-00\nC\nUTC\n\n\n\n\n\n\nNote that the month names vary, as does the time, and even the date! The safest choice is to form timestamps with respect to a fixed locale and time zone (presumably the non-geographic choices represented by “Computer World!” above).\nYou do some research and learn that you can force a certain locale via Sys.setlocale() and force a certain time zone by setting the TZ environment variable. Specifically, we set the LC_TIME component of the locale to “C” and the time zone to “UTC” (Coordinated Universal Time). Here’s your first attempt to improve timestamp():\n\ntimestamp <- function(time = Sys.time()) {\n Sys.setlocale(\"LC_TIME\", \"C\")\n Sys.setenv(TZ = \"UTC\")\n format(time, \"%Y-%B-%d_%H-%M-%S\")\n}\n\nBut your Brazilian colleague notices that datetimes print differently, before and after she uses outfile_path() from your package:\nBefore:\n\nformat(Sys.time(), \"%Y-%B-%d_%H-%M-%S\")\n\n\n#> [1] \"2024-janeiro-22_04-14-11\"\n\nAfter:\n\noutfile_path(\"INFILE.csv\")\n#> [1] \"2024-January-22_07-14-10_INFILE_clean.csv\"\n\nformat(Sys.time(), \"%Y-%B-%d_%H-%M-%S\")\n#> [1] \"2024-January-22_07-14-11\"\n\nNotice that her month name switched from Portuguese to English and the time is clearly being reported in a different time zone. The calls to Sys.setlocale() and Sys.setenv() inside timestamp() have made persistent (and very surprising) changes to her R session. This sort of side effect is very undesirable and is extremely difficult to track down and debug, especially in more complicated settings.\nHere are better versions of timestamp():\n\n# use withr::local_*() functions to keep the changes local to timestamp()\ntimestamp <- function(time = Sys.time()) {\n withr::local_locale(c(\"LC_TIME\" = \"C\"))\n withr::local_timezone(\"UTC\")\n format(time, \"%Y-%B-%d_%H-%M-%S\")\n}\n\n# use the tz argument to format.POSIXct()\ntimestamp <- function(time = Sys.time()) {\n withr::local_locale(c(\"LC_TIME\" = \"C\"))\n format(time, \"%Y-%B-%d_%H-%M-%S\", tz = \"UTC\")\n}\n\n# put the format() call inside withr::with_*()\ntimestamp <- function(time = Sys.time()) {\n withr::with_locale(\n c(\"LC_TIME\" = \"C\"),\n format(time, \"%Y-%B-%d_%H-%M-%S\", tz = \"UTC\")\n )\n}\n\nThese show various methods to limit the scope of our changes to LC_TIME and the timezone. A good rule of thumb is to make the scope of such changes as narrow as possible and practical. The tz argument of format() is the most surgical way to deal with the timezone, but nothing similar exists for LC_TIME. We make the temporary locale modification using the withr package, which provides a very flexible toolkit for temporary state changes. This (and base::on.exit()) are discussed further in Section 6.5. Note that if you use withr as we do above, you would need to list it in DESCRIPTION in Imports (Chapter 11, Section 10.1.3).\nThis underscores a point from the previous section: you need to adopt a different mindset when defining functions inside a package. Try to avoid making any changes to the user’s overall state. If such changes are unavoidable, make sure to reverse them (if possible) or to document them explicitly (if related to the function’s primary purpose)." }, { "objectID": "package-within.html#concluding-thoughts", @@ -585,7 +585,7 @@ "href": "dependencies-mindset-background.html#sec-dependencies-namespace", "title": "10  Dependencies: Mindset and Background", "section": "\n10.2 Namespace", - "text": "10.2 Namespace\nSo far, we’ve explained the mechanics of declaring a dependency in DESCRIPTION (Section 9.6) and how to analyze the costs and benefits of dependencies (Section 10.1). Before we explain how to use your dependencies in various parts of your package in Chapter 11, we need to establish the concepts of a package namespace and the search path.\n\n10.2.1 Motivation\nAs the name suggests, namespaces provide “spaces” for “names”. They provide a context for looking up the value of an object associated with a name.\nWithout knowing it, you’ve probably already used namespaces. Have you ever used the :: operator? It disambiguates functions with the same name. For example, both the lubridate and here packages provide a here() function. If you attach lubridate, then here, here() will refer to the here version, because the last package attached wins. But if you attach the packages in the opposite order, here() will refer to the lubridate version.\n\nlibrary(lubridate) | library(here)\nlibrary(here) | library(lubridate)\n\nhere() # here::here() | here() # lubridate::here()\n\nThis can be confusing. Instead, you can qualify the function call with a specific namespace: lubridate::here() and here::here(). Then the order in which the packages are attached won’t matter4.\n\nlubridate::here() # always gets lubridate::here()\nhere::here() # always gets here::here()\n\nAs you will see in Section 11.4, the package::function() calling style is also our default recommendation for how to use your dependencies in the code below R/, because it eliminates all ambiguity.\nBut, in the context of package code, the use of :: is not really our main line of defense against the confusion seen in the example above. In packages, we rely on namespaces to ensure that every package works the same way regardless of what packages are attached by the user.\nConsider the sd() function from the stats package that is part of base R:\n\nsd\n#> function (x, na.rm = FALSE) \n#> sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x), \n#> na.rm = na.rm))\n#> <bytecode: 0x563f6ecf3080>\n#> <environment: namespace:stats>\n\nIt’s defined in terms of another function, var(), also from the stats package. So what happens if we override var() with our own definition? Does it break sd()?\n\nvar <- function(x) -5\nvar(1:5)\n#> [1] -5\n\nsd(1:5)\n#> [1] 1.58\n\nSurprisingly, it does not! That’s because when sd() looks for an object called var(), it looks first in the stats package namespace, so it finds stats::var(), not the var() we created in the global environment. It would be chaos if functions like sd() could be broken by a user redefining var() or by attaching a package that overrides var(). The package namespace system is what saves us from this fate.\n\n10.2.2 The NAMESPACE file\nThe NAMESPACE file plays a key role in defining your package’s namespace. Here are selected lines from the NAMESPACE file in the testthat package:\n# Generated by roxygen2: do not edit by hand\n\nS3method(compare,character)\nS3method(print,testthat_results)\nexport(compare)\nexport(expect_equal)\nimport(rlang)\nimportFrom(brio,readLines)\nuseDynLib(testthat, .registration = TRUE)\nThe first line announces that this file is not written by hand, but rather is generated by the roxygen2 package. We’ll return to this topic soon, after we discuss the remaining lines.\nYou can see that the NAMESPACE file looks a bit like R code (but it is not). Each line contains a directive: S3method(), export(), importFrom(), and so on. Each directive describes an R object, and says whether it’s exported from this package to be used by others, or it’s imported from another package to be used internally.\nThese directives are the most important in our development approach, in order of frequency:\n\n\nexport(): export a function (including S3 and S4 generics).\n\nS3method(): export an S3 method.\n\nimportFrom(): import selected object from another namespace (including S4 generics).\n\nimport(): import all objects from another package’s namespace.\n\nuseDynLib(): registers routines from a DLL (this is specific to packages with compiled code).\n\nThere are other directives that we won’t cover here, because they are explicitly discouraged or they just rarely come up in our development work.\n\n\nexportPattern(): exports all functions that match a pattern. We feel it’s safer to always use explicit exports and we avoid the use of this directive.\n\nexportClasses(), exportMethods(), importClassesFrom(), importMethodsFrom(): export and import S4 classes and methods. We only work in the S4 system when necessary for compatibility with another package, i.e. we generally don’t implement methods or classes that we own with S4. Therefore the S4 coverage in this book is very minimal.\n\nIn the devtools workflow, the NAMESPACE file is not written by hand! Instead, we prefer to generate NAMESPACE with the roxygen2 package, using specific tags located in a roxygen comment above each function’s definition in the R/*.R files (Section 11.3). We will have much more to say about roxygen comments and the roxygen2 package when we discuss package documentation in Chapter 16. For now, we just lay out the reasons we prefer this method of generating the NAMESPACE file:\n\nNamespace tags are integrated into the source code, so when you read the code it’s easier to see what’s being exported and imported and why.\nRoxygen2 abstracts away some of the details of NAMESPACE. You only need to learn one tag, @export, and roxygen2 will figure out which specific directive to use, based on whether the associated object is a regular function, S3 method, S4 method, or S4 class.\nRoxygen2 keeps NAMESPACE tidy. No matter how many times @importFrom foo bar appears in your roxygen comments, you’ll only get one importFrom(foo, bar) in your NAMESPACE. Roxygen2 also keeps NAMESPACE organised in a principled order, sorting first by the directive type and then alphabetically. Roxygen2 takes away the burden of writing NAMESPACE, while also trying to keep the file as readable as possible. This organization also makes Git diffs much more informative.\n\nNote that you can choose to use roxygen2 to generate just NAMESPACE, just man/*.Rd (Chapter 16), or both (as is our practice). If you don’t use any namespace-related tags, roxygen2 won’t touch NAMESPACE. If you don’t use any documentation-related tags, roxygen2 won’t touch man/." + "text": "10.2 Namespace\nSo far, we’ve explained the mechanics of declaring a dependency in DESCRIPTION (Section 9.6) and how to analyze the costs and benefits of dependencies (Section 10.1). Before we explain how to use your dependencies in various parts of your package in Chapter 11, we need to establish the concepts of a package namespace and the search path.\n\n10.2.1 Motivation\nAs the name suggests, namespaces provide “spaces” for “names”. They provide a context for looking up the value of an object associated with a name.\nWithout knowing it, you’ve probably already used namespaces. Have you ever used the :: operator? It disambiguates functions with the same name. For example, both the lubridate and here packages provide a here() function. If you attach lubridate, then here, here() will refer to the here version, because the last package attached wins. But if you attach the packages in the opposite order, here() will refer to the lubridate version.\n\nlibrary(lubridate) | library(here)\nlibrary(here) | library(lubridate)\n\nhere() # here::here() | here() # lubridate::here()\n\nThis can be confusing. Instead, you can qualify the function call with a specific namespace: lubridate::here() and here::here(). Then the order in which the packages are attached won’t matter4.\n\nlubridate::here() # always gets lubridate::here()\nhere::here() # always gets here::here()\n\nAs you will see in Section 11.4, the package::function() calling style is also our default recommendation for how to use your dependencies in the code below R/, because it eliminates all ambiguity.\nBut, in the context of package code, the use of :: is not really our main line of defense against the confusion seen in the example above. In packages, we rely on namespaces to ensure that every package works the same way regardless of what packages are attached by the user.\nConsider the sd() function from the stats package that is part of base R:\n\nsd\n#> function (x, na.rm = FALSE) \n#> sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x), \n#> na.rm = na.rm))\n#> <bytecode: 0x55f465913560>\n#> <environment: namespace:stats>\n\nIt’s defined in terms of another function, var(), also from the stats package. So what happens if we override var() with our own definition? Does it break sd()?\n\nvar <- function(x) -5\nvar(1:5)\n#> [1] -5\n\nsd(1:5)\n#> [1] 1.58\n\nSurprisingly, it does not! That’s because when sd() looks for an object called var(), it looks first in the stats package namespace, so it finds stats::var(), not the var() we created in the global environment. It would be chaos if functions like sd() could be broken by a user redefining var() or by attaching a package that overrides var(). The package namespace system is what saves us from this fate.\n\n10.2.2 The NAMESPACE file\nThe NAMESPACE file plays a key role in defining your package’s namespace. Here are selected lines from the NAMESPACE file in the testthat package:\n# Generated by roxygen2: do not edit by hand\n\nS3method(compare,character)\nS3method(print,testthat_results)\nexport(compare)\nexport(expect_equal)\nimport(rlang)\nimportFrom(brio,readLines)\nuseDynLib(testthat, .registration = TRUE)\nThe first line announces that this file is not written by hand, but rather is generated by the roxygen2 package. We’ll return to this topic soon, after we discuss the remaining lines.\nYou can see that the NAMESPACE file looks a bit like R code (but it is not). Each line contains a directive: S3method(), export(), importFrom(), and so on. Each directive describes an R object, and says whether it’s exported from this package to be used by others, or it’s imported from another package to be used internally.\nThese directives are the most important in our development approach, in order of frequency:\n\n\nexport(): export a function (including S3 and S4 generics).\n\nS3method(): export an S3 method.\n\nimportFrom(): import selected object from another namespace (including S4 generics).\n\nimport(): import all objects from another package’s namespace.\n\nuseDynLib(): registers routines from a DLL (this is specific to packages with compiled code).\n\nThere are other directives that we won’t cover here, because they are explicitly discouraged or they just rarely come up in our development work.\n\n\nexportPattern(): exports all functions that match a pattern. We feel it’s safer to always use explicit exports and we avoid the use of this directive.\n\nexportClasses(), exportMethods(), importClassesFrom(), importMethodsFrom(): export and import S4 classes and methods. We only work in the S4 system when necessary for compatibility with another package, i.e. we generally don’t implement methods or classes that we own with S4. Therefore the S4 coverage in this book is very minimal.\n\nIn the devtools workflow, the NAMESPACE file is not written by hand! Instead, we prefer to generate NAMESPACE with the roxygen2 package, using specific tags located in a roxygen comment above each function’s definition in the R/*.R files (Section 11.3). We will have much more to say about roxygen comments and the roxygen2 package when we discuss package documentation in Chapter 16. For now, we just lay out the reasons we prefer this method of generating the NAMESPACE file:\n\nNamespace tags are integrated into the source code, so when you read the code it’s easier to see what’s being exported and imported and why.\nRoxygen2 abstracts away some of the details of NAMESPACE. You only need to learn one tag, @export, and roxygen2 will figure out which specific directive to use, based on whether the associated object is a regular function, S3 method, S4 method, or S4 class.\nRoxygen2 keeps NAMESPACE tidy. No matter how many times @importFrom foo bar appears in your roxygen comments, you’ll only get one importFrom(foo, bar) in your NAMESPACE. Roxygen2 also keeps NAMESPACE organised in a principled order, sorting first by the directive type and then alphabetically. Roxygen2 takes away the burden of writing NAMESPACE, while also trying to keep the file as readable as possible. This organization also makes Git diffs much more informative.\n\nNote that you can choose to use roxygen2 to generate just NAMESPACE, just man/*.Rd (Chapter 16), or both (as is our practice). If you don’t use any namespace-related tags, roxygen2 won’t touch NAMESPACE. If you don’t use any documentation-related tags, roxygen2 won’t touch man/." }, { "objectID": "dependencies-mindset-background.html#sec-dependencies-search", @@ -942,7 +942,7 @@ "href": "website.html#initiate-a-site", "title": "19  Website", "section": "\n19.1 Initiate a site", - "text": "19.1 Initiate a site\nAssuming your package has a valid structure, pkgdown should be able to make a website for it. Obviously that website will be more substantial if your package has more of the documentation elements listed above. But something reasonable should happen for any valid R package.\n\n\n\n\n\n\nTip\n\n\n\nWe hear that some folks put off “learning pkgdown”, because they think it’s going to be a lot of work. But then they eventually execute the two commands we show next and have a decent website in less than five minutes!\n\n\nusethis::use_pkgdown() is a function you run once and it does the initial, minimal setup necessary to start using pkgdown:\n\nusethis::use_pkgdown()\n\n\n#> ✔ Setting active project to '/tmp/RtmpDt2f46/mypackage'\n#> ✔ Adding '^_pkgdown\\\\.yml$', '^docs$', '^pkgdown$' to '.Rbuildignore'\n#> ✔ Adding 'docs' to '.gitignore'\n#> ✔ Writing '_pkgdown.yml'\n#> • Edit '_pkgdown.yml'\n#> ✔ Setting active project to '<no active project>'\n\nHere’s what use_pkgdown() does:\n\nCreates _pkgdown.yml, which is the main configuration file for pkgdown. In an interactive session, _pkgdown.yml will be opened for inspection and editing. But there’s no immediate need to change or add anything here.\nAdds various patterns to .Rbuildignore, to keep pkgdown-specific files and directories from being included in your package bundle.\nAdds docs, the default destination for a rendered site, to .gitignore. This is harmless for those who don’t use Git. For those who do, this opts you in to our recommended lifestyle, where the definitive source for your pkgdown site is built and deployed elsewhere (probably via GitHub Actions and Pages; more on this soon). This means the rendered website at docs/ just serves as a local preview.\n\npkgdown::build_site() is a function you’ll call repeatedly, to re-render your site locally. In an extremely barebones package, you’ll see something like this:\n\npkgdown::build_site()\n\n\n#> ✔ Setting active project to '/tmp/RtmpDt2f46/mypackage'\n#> -- Installing package into temporary library -----------------------\n#> == Building pkgdown site =======================================================\n#> Reading from: '/tmp/RtmpDt2f46/mypackage'\n#> Writing to: '/tmp/RtmpDt2f46/mypackage/docs'\n#> -- Initialising site -----------------------------------------------------------\n#> Copying '../../../home/runner/work/_temp/Library/pkgdown/BS5/assets/link.svg' to 'link.svg'\n#> Copying '../../../home/runner/work/_temp/Library/pkgdown/BS5/assets/pkgdown.js' to 'pkgdown.js'\n#> -- Building home ---------------------------------------------------------------\n#> Writing 'authors.html'\n#> Writing '404.html'\n#> -- Building function reference -------------------------------------------------\n#> Writing 'reference/index.html'\n#> Writing 'sitemap.xml'\n#> -- Building search index -------------------------------------------------------\n#> == DONE ========================================================================\n#> ✔ Setting active project to '<no active project>'\n\nIn an interactive session your newly rendered site should appear in your default web browser.\n\n\n\n\n\n\nRStudio\n\n\n\nAnother nice gesture to build your site is via Addins > pkgdown > Build pkgdown.\n\n\nYou can look in the local docs/ directory to see the files that constitute your package’s website. To manually browse the site, open docs/index.html in your preferred browser.\nThis is almost all you truly need to know about pkgdown. It’s certainly a great start and, as your package and ambitions grow, the best place to learn more is the pkgdown-made website for the pkgdown package itself: https://pkgdown.r-lib.org." + "text": "19.1 Initiate a site\nAssuming your package has a valid structure, pkgdown should be able to make a website for it. Obviously that website will be more substantial if your package has more of the documentation elements listed above. But something reasonable should happen for any valid R package.\n\n\n\n\n\n\nTip\n\n\n\nWe hear that some folks put off “learning pkgdown”, because they think it’s going to be a lot of work. But then they eventually execute the two commands we show next and have a decent website in less than five minutes!\n\n\nusethis::use_pkgdown() is a function you run once and it does the initial, minimal setup necessary to start using pkgdown:\n\nusethis::use_pkgdown()\n\n\n#> ✔ Setting active project to '/tmp/RtmpoTzg9a/mypackage'\n#> ✔ Adding '^_pkgdown\\\\.yml$', '^docs$', '^pkgdown$' to '.Rbuildignore'\n#> ✔ Adding 'docs' to '.gitignore'\n#> ✔ Writing '_pkgdown.yml'\n#> • Edit '_pkgdown.yml'\n#> ✔ Setting active project to '<no active project>'\n\nHere’s what use_pkgdown() does:\n\nCreates _pkgdown.yml, which is the main configuration file for pkgdown. In an interactive session, _pkgdown.yml will be opened for inspection and editing. But there’s no immediate need to change or add anything here.\nAdds various patterns to .Rbuildignore, to keep pkgdown-specific files and directories from being included in your package bundle.\nAdds docs, the default destination for a rendered site, to .gitignore. This is harmless for those who don’t use Git. For those who do, this opts you in to our recommended lifestyle, where the definitive source for your pkgdown site is built and deployed elsewhere (probably via GitHub Actions and Pages; more on this soon). This means the rendered website at docs/ just serves as a local preview.\n\npkgdown::build_site() is a function you’ll call repeatedly, to re-render your site locally. In an extremely barebones package, you’ll see something like this:\n\npkgdown::build_site()\n\n\n#> ✔ Setting active project to '/tmp/RtmpoTzg9a/mypackage'\n#> -- Installing package into temporary library -----------------------\n#> == Building pkgdown site =======================================================\n#> Reading from: '/tmp/RtmpoTzg9a/mypackage'\n#> Writing to: '/tmp/RtmpoTzg9a/mypackage/docs'\n#> -- Initialising site -----------------------------------------------------------\n#> Copying '../../../home/runner/work/_temp/Library/pkgdown/BS5/assets/link.svg' to 'link.svg'\n#> Copying '../../../home/runner/work/_temp/Library/pkgdown/BS5/assets/pkgdown.js' to 'pkgdown.js'\n#> -- Building home ---------------------------------------------------------------\n#> Writing 'authors.html'\n#> Writing '404.html'\n#> -- Building function reference -------------------------------------------------\n#> Writing 'reference/index.html'\n#> Writing 'sitemap.xml'\n#> -- Building search index -------------------------------------------------------\n#> == DONE ========================================================================\n#> ✔ Setting active project to '<no active project>'\n\nIn an interactive session your newly rendered site should appear in your default web browser.\n\n\n\n\n\n\nRStudio\n\n\n\nAnother nice gesture to build your site is via Addins > pkgdown > Build pkgdown.\n\n\nYou can look in the local docs/ directory to see the files that constitute your package’s website. To manually browse the site, open docs/index.html in your preferred browser.\nThis is almost all you truly need to know about pkgdown. It’s certainly a great start and, as your package and ambitions grow, the best place to learn more is the pkgdown-made website for the pkgdown package itself: https://pkgdown.r-lib.org." }, { "objectID": "website.html#sec-website-deployment", diff --git a/sitemap.xml b/sitemap.xml index 11470c38c..8cc4eefe7 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,218 +2,218 @@ https://r-pkgs.org/book-asciidoc/R-Packages--2e-.adoc - 2024-01-21T07:12:15.888Z + 2024-01-22T07:12:12.748Z https://r-pkgs.org/index.html - 2024-01-21T07:17:19.239Z + 2024-01-22T07:16:48.035Z https://r-pkgs.org/book-asciidoc/preface.adoc - 2024-01-21T07:12:22.864Z + 2024-01-22T07:12:19.528Z https://r-pkgs.org/preface.html - 2024-01-21T07:17:19.263Z + 2024-01-22T07:16:48.059Z https://r-pkgs.org/book-asciidoc/introduction.adoc - 2024-01-21T07:12:28.676Z + 2024-01-22T07:12:25.040Z https://r-pkgs.org/introduction.html - 2024-01-21T07:17:19.271Z + 2024-01-22T07:16:48.067Z https://r-pkgs.org/book-asciidoc/whole-game.adoc - 2024-01-21T07:13:53.431Z + 2024-01-22T07:13:42.216Z https://r-pkgs.org/whole-game.html - 2024-01-21T07:17:19.311Z + 2024-01-22T07:16:48.103Z https://r-pkgs.org/book-asciidoc/setup.adoc - 2024-01-21T07:14:01.991Z + 2024-01-22T07:13:49.568Z https://r-pkgs.org/setup.html - 2024-01-21T07:17:19.319Z + 2024-01-22T07:16:48.111Z https://r-pkgs.org/book-asciidoc/structure.adoc - 2024-01-21T07:14:11.355Z + 2024-01-22T07:13:57.660Z https://r-pkgs.org/structure.html - 2024-01-21T07:17:19.343Z + 2024-01-22T07:16:48.131Z https://r-pkgs.org/book-asciidoc/workflow101.adoc - 2024-01-21T07:14:20.507Z + 2024-01-22T07:14:05.948Z https://r-pkgs.org/workflow101.html - 2024-01-21T07:17:19.359Z + 2024-01-22T07:16:48.147Z https://r-pkgs.org/book-asciidoc/package-within.adoc - 2024-01-21T07:14:31.643Z + 2024-01-22T07:14:15.636Z https://r-pkgs.org/package-within.html - 2024-01-21T07:17:19.403Z + 2024-01-22T07:16:48.187Z https://r-pkgs.org/book-asciidoc/code.adoc - 2024-01-21T07:14:43.771Z + 2024-01-22T07:14:26.932Z https://r-pkgs.org/code.html - 2024-01-21T07:17:19.435Z + 2024-01-22T07:16:48.219Z https://r-pkgs.org/book-asciidoc/data.adoc - 2024-01-21T07:14:55.791Z + 2024-01-22T07:14:37.792Z https://r-pkgs.org/data.html - 2024-01-21T07:17:19.459Z + 2024-01-22T07:16:48.243Z https://r-pkgs.org/book-asciidoc/misc.adoc - 2024-01-21T07:15:03.927Z + 2024-01-22T07:14:44.756Z https://r-pkgs.org/misc.html - 2024-01-21T07:17:19.471Z + 2024-01-22T07:16:48.251Z https://r-pkgs.org/book-asciidoc/description.adoc - 2024-01-21T07:15:10.323Z + 2024-01-22T07:14:50.964Z https://r-pkgs.org/description.html - 2024-01-21T07:17:19.491Z + 2024-01-22T07:16:48.275Z https://r-pkgs.org/book-asciidoc/dependencies-mindset-background.adoc - 2024-01-21T07:15:22.455Z + 2024-01-22T07:15:01.328Z https://r-pkgs.org/dependencies-mindset-background.html - 2024-01-21T07:17:19.511Z + 2024-01-22T07:16:48.295Z https://r-pkgs.org/book-asciidoc/dependencies-in-practice.adoc - 2024-01-21T07:15:31.515Z + 2024-01-22T07:15:09.220Z https://r-pkgs.org/dependencies-in-practice.html - 2024-01-21T07:17:19.547Z + 2024-01-22T07:16:48.327Z https://r-pkgs.org/book-asciidoc/license.adoc - 2024-01-21T07:15:41.547Z + 2024-01-22T07:15:18.316Z https://r-pkgs.org/license.html - 2024-01-21T07:17:19.559Z + 2024-01-22T07:16:48.339Z https://r-pkgs.org/book-asciidoc/testing-basics.adoc - 2024-01-21T07:15:48.115Z + 2024-01-22T07:15:24.660Z https://r-pkgs.org/testing-basics.html - 2024-01-21T07:17:19.583Z + 2024-01-22T07:16:48.363Z https://r-pkgs.org/book-asciidoc/testing-design.adoc - 2024-01-21T07:15:57.391Z + 2024-01-22T07:15:32.972Z https://r-pkgs.org/testing-design.html - 2024-01-21T07:17:19.659Z + 2024-01-22T07:16:48.435Z https://r-pkgs.org/book-asciidoc/testing-advanced.adoc - 2024-01-21T07:16:05.919Z + 2024-01-22T07:15:40.384Z https://r-pkgs.org/testing-advanced.html - 2024-01-21T07:17:19.679Z + 2024-01-22T07:16:48.459Z https://r-pkgs.org/book-asciidoc/man.adoc - 2024-01-21T07:16:13.587Z + 2024-01-22T07:15:47.928Z https://r-pkgs.org/man.html - 2024-01-21T07:17:19.711Z + 2024-01-22T07:16:48.487Z https://r-pkgs.org/book-asciidoc/vignettes.adoc - 2024-01-21T07:16:23.379Z + 2024-01-22T07:15:56.576Z https://r-pkgs.org/vignettes.html - 2024-01-21T07:17:19.731Z + 2024-01-22T07:16:48.507Z https://r-pkgs.org/book-asciidoc/other-markdown.adoc - 2024-01-21T07:16:31.555Z + 2024-01-22T07:16:03.748Z https://r-pkgs.org/other-markdown.html - 2024-01-21T07:17:19.743Z + 2024-01-22T07:16:48.519Z https://r-pkgs.org/book-asciidoc/website.adoc - 2024-01-21T07:16:43.931Z + 2024-01-22T07:16:15.728Z https://r-pkgs.org/website.html - 2024-01-21T07:17:19.763Z + 2024-01-22T07:16:48.539Z https://r-pkgs.org/book-asciidoc/software-development-practices.adoc - 2024-01-21T07:16:50.463Z + 2024-01-22T07:16:21.456Z https://r-pkgs.org/software-development-practices.html - 2024-01-21T07:17:19.775Z + 2024-01-22T07:16:48.551Z https://r-pkgs.org/book-asciidoc/lifecycle.adoc - 2024-01-21T07:16:59.403Z + 2024-01-22T07:16:30.191Z https://r-pkgs.org/lifecycle.html - 2024-01-21T07:17:19.803Z + 2024-01-22T07:16:48.579Z https://r-pkgs.org/book-asciidoc/release.adoc - 2024-01-21T07:17:07.667Z + 2024-01-22T07:16:37.719Z https://r-pkgs.org/release.html - 2024-01-21T07:17:19.819Z + 2024-01-22T07:16:48.595Z https://r-pkgs.org/book-asciidoc/references.adoc - 2024-01-21T07:17:09.831Z + 2024-01-22T07:16:39.835Z https://r-pkgs.org/references.html - 2024-01-21T07:17:19.831Z + 2024-01-22T07:16:48.607Z https://r-pkgs.org/book-asciidoc/R-CMD-check.adoc - 2024-01-21T07:17:14.635Z + 2024-01-22T07:16:44.375Z https://r-pkgs.org/R-CMD-check.html - 2024-01-21T07:17:19.847Z + 2024-01-22T07:16:48.623Z diff --git a/website.html b/website.html index 18a54d382..7b1a09c97 100644 --- a/website.html +++ b/website.html @@ -443,7 +443,7 @@

usethis::use_pkgdown()
-
#> ✔ Setting active project to '/tmp/RtmpDt2f46/mypackage'
+
#> ✔ Setting active project to '/tmp/RtmpoTzg9a/mypackage'
 #> ✔ Adding '^_pkgdown\\.yml$', '^docs$', '^pkgdown$' to '.Rbuildignore'
 #> ✔ Adding 'docs' to '.gitignore'
 #> ✔ Writing '_pkgdown.yml'
@@ -461,11 +461,11 @@ 

pkgdown::build_site()

-
#> ✔ Setting active project to '/tmp/RtmpDt2f46/mypackage'
+
#> ✔ Setting active project to '/tmp/RtmpoTzg9a/mypackage'
 #> -- Installing package into temporary library -----------------------
 #> == Building pkgdown site =======================================================
-#> Reading from: '/tmp/RtmpDt2f46/mypackage'
-#> Writing to:   '/tmp/RtmpDt2f46/mypackage/docs'
+#> Reading from: '/tmp/RtmpoTzg9a/mypackage'
+#> Writing to:   '/tmp/RtmpoTzg9a/mypackage/docs'
 #> -- Initialising site -----------------------------------------------------------
 #> Copying '../../../home/runner/work/_temp/Library/pkgdown/BS5/assets/link.svg' to 'link.svg'
 #> Copying '../../../home/runner/work/_temp/Library/pkgdown/BS5/assets/pkgdown.js' to 'pkgdown.js'
diff --git a/whole-game.html b/whole-game.html
index 6ba5978c4..d960d557e 100644
--- a/whole-game.html
+++ b/whole-game.html
@@ -482,8 +482,8 @@ 

For the creation of this book we have to work in a temporary directory, because the book is built non-interactively in the cloud. Behind the scenes, we’re executing our own create_package() command, but don’t be surprised if our output differs a bit from yours.

-
#> ✔ Creating '/tmp/RtmpfU7Z6e/regexcite/'
-#> ✔ Setting active project to '/tmp/RtmpfU7Z6e/regexcite'
+
#> ✔ Creating '/tmp/RtmpBET4N9/regexcite/'
+#> ✔ Setting active project to '/tmp/RtmpBET4N9/regexcite'
 #> ✔ Creating 'R/'
 #> ✔ Writing 'DESCRIPTION'
 #> Package: regexcite
@@ -610,7 +610,7 @@ 

message -502b140b45… +0c2fae2443… jennybc Initial commit @@ -761,7 +761,7 @@

── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────
-Duration: 7.2s
+Duration: 6.6s
 
 ❯ checking DESCRIPTION meta-information ... WARNING
   Non-standard license specification:
@@ -922,7 +922,7 @@ 

── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────
-Duration: 8.9s
+Duration: 8s
 
 0 errors ✔ | 0 warnings ✔ | 0 notes ✔
@@ -935,14 +935,14 @@

── R CMD build ─────────────────────────────────────────────────────
-* checking for file ‘/tmp/RtmpfU7Z6e/regexcite/DESCRIPTION’ ... OK
+* checking for file ‘/tmp/RtmpBET4N9/regexcite/DESCRIPTION’ ... OK
 * preparing ‘regexcite’:
 * checking DESCRIPTION meta-information ... OK
 * checking for LF line-endings in source and make files and shell scripts
 * checking for empty or unneeded directories
 * building ‘regexcite_0.0.0.9000.tar.gz’
 Running /opt/R/4.3.2/lib/R/bin/R CMD INSTALL \
-  /tmp/RtmpfU7Z6e/regexcite_0.0.0.9000.tar.gz --install-tests 
+  /tmp/RtmpBET4N9/regexcite_0.0.0.9000.tar.gz --install-tests 
 * installing to library ‘/home/runner/work/_temp/Library’
 * installing *source* package ‘regexcite’ ...
 ** using staged installation
@@ -1248,7 +1248,7 @@ 

build_readme()
 #> ℹ Installing regexcite in temporary library
-#> ℹ Building '/tmp/RtmpfU7Z6e/regexcite/README.Rmd'
+#> ℹ Building '/tmp/RtmpBET4N9/regexcite/README.Rmd'

You can see the rendered README.md simply by visiting regexcite on GitHub.

Finally, don’t forget to do one last commit. And push, if you’re using GitHub.

@@ -1261,7 +1261,7 @@

── R CMD check results ─────────────────── regexcite 0.0.0.9000 ────
-Duration: 10.1s
+Duration: 9.2s
 
 0 errors ✔ | 0 warnings ✔ | 0 notes ✔
@@ -1271,7 +1271,7 @@

── R CMD build ─────────────────────────────────────────────────────
-* checking for file ‘/tmp/RtmpfU7Z6e/regexcite/DESCRIPTION’ ... OK
+* checking for file ‘/tmp/RtmpBET4N9/regexcite/DESCRIPTION’ ... OK
 * preparing ‘regexcite’:
 * checking DESCRIPTION meta-information ... OK
 * checking for LF line-endings in source and make files and shell scripts
@@ -1279,7 +1279,7 @@