Skip to content

Commit

Permalink
Fresh chapter on rendering R scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
jennybc committed Oct 26, 2021
1 parent 0995bde commit 2ba7aa2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 28 deletions.
6 changes: 3 additions & 3 deletions render-r-script-demo.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
R scripts can be rendered!
================
Jenny Bryan
April 1, 2014
jenny
2021-10-25

Here’s some prose in a very special comment. Let’s summarize the
built-in dataset `VADeaths`.

``` r
## here is a regular code comment, that will remain as such
# here is a regular code comment, that will remain as such
summary(VADeaths)
```

Expand Down
66 changes: 41 additions & 25 deletions usage-r-script-and-github.Rmd
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
# Render an R script {#r-test-drive}

An underappreciated fact is that much of what you can do with R Markdown, you can also do with an R script.
An under-appreciated fact is that much of what you can do with R Markdown, you can also do with an R script.

If you're in analysis mode and want a report as a side effect, write an R script. If you're writing a report with a lot of R code in it, write Rmd. In either case, render to markdown and/or HTML to communicate with other human beings.
If you're in analysis mode and want a report as a side effect, write an R script.
If you're writing a report with a lot of R code in it, write `.Rmd`.
In either case, render to markdown and/or HTML to communicate with other human beings.

* In R markdown, prose is top-level and code is tucked into chunks.
* In R scripts, code is top-level and prose is tucked into comments. You will use `#'` to request that certain comments appear as top-level prose in the rendered output.
* In R markdown, prose is top-level and code is tucked into chunks.
* In R scripts, code is top-level and prose is tucked into comments.
You will use `#'` to request that certain comments appear as top-level prose
in the rendered output.

You will continue to specify things like the output format via YAML at the top of the file. This will need to be commented with `#'`.
You will continue to specify things like the output format via YAML at the top of the file.
This will need to be commented with `#'`.

## Morph R Markdown into a renderable R script

Get yourself a working R Markdown file, such as the one you made in your [Rmd test drive](#rmd-test-drive). Or use the boilerplate Rmd document RStudio makes with *File > New File > R Markdown ...*.
Get yourself a working R Markdown file, such as the one you made in your [Rmd test drive](#rmd-test-drive).
Or use the boilerplate `.Rmd` document RStudio makes with *File > New File > R Markdown ...*.

Save the file as `foo.R`, as opposed to `foo.Rmd`. Yes, for a brief moment, you will have R Markdown saved as an R script, but that won't be true for long.
Save the file as `foo.R`, as opposed to `foo.Rmd`.
Yes, for a brief moment, you will have R Markdown saved as an R script, but that won't be true for long.

Transform the Rmd to R:
Transform the R markdown to R:

* Anything that's not R code? Like the YAML and the English prose? Protect it with roxygen-style comments: start each line with `#'`.
* Anything that's R code? Let it exist "as is" as top-level code. That means you'll need to change the syntax of R chunk headers like so:
* Anything that's not R code?
Like the YAML and the prose?
Protect it with roxygen-style comments: start each line with `#'`.
* Anything that is R code?
Let it exist "as is" as top-level code.
That means you'll need to change the syntax of R chunk headers like so:

Before: ` ```{r setup, include = FALSE}`
After: `#+ r setup, include = FALSE`
Expand All @@ -29,15 +40,18 @@ Transform the Rmd to R:

Render the R script through one of these methods:

* Click on the "notebook" icon in RStudio to "Compile Report".
* In RStudio, do *File > Knit Document*.
* In R, do `rmarkdown::render("foo.R")`.
* Click on the "notebook" icon in RStudio to "Compile Report".
* In RStudio, do *File > Knit Document*.
* In R, do `rmarkdown::render("foo.R")`.

You'll get a markdown and/or HTML report, just as with R Markdown.

If you're having trouble making all the necessary changes and you're frustrated, see below for an example you can copy and paste.

All the workflow tips from the [Rmd test drive](#rmd-test-drive) apply here: when you script an analysis, render it to markdown, commit the `.R`, the `.md`, any associated figures, and push to GitHub. Collaborators can see your code but also browse the result without running it. This makes the current state of your analysis accessible to someone who does not even run R or who wants to take a quick look at things from a cell phone or while on vacation.
All the workflow tips from the [Rmd test drive](#rmd-test-drive) apply here:
when you script an analysis, render it to markdown, commit the `.R`, the `.md`, any associated figures, and push to GitHub.
Collaborators can see your code, but also browse around the results without having to download and execute the code.
This makes the current state of your analysis accessible to someone who does not even run R or who wants to take a quick look at things from a cell phone or while on vacation.

## Write a render-ready R script

Expand All @@ -54,7 +68,7 @@ va_home <- fs::dir_create(fs::file_temp(pattern = "va-example-"))
demo_code <- c(
"#' Here's some prose in a very special comment. Let's summarize the built-in",
"#' dataset `VADeaths`.",
"## here is a regular code comment, that will remain as such",
"# here is a regular code comment, that will remain as such",
"summary(VADeaths)",
"",
"#' Here's some more prose. I can use usual markdown syntax to make things",
Expand All @@ -76,16 +90,16 @@ Render the R script through one of these methods:
* In RStudio, do *File > Knit Document*.
* In R, do `rmarkdown::render("YOURSCRIPT.R")`.

Revel in your attractive looking report with almost zero effort! Seriously, all you had to do was think about when to use special comments `#'` in order to promote that to nicely rendered text.
Revel in your attractive looking report with almost zero effort!
Seriously, all you had to do was think about when to use special comments `#'` in order to promote that to nicely rendered text.

Drawing on the workflow tips in [Rmd test drive](#rmd-test-drive), let's add some YAML frontmatter, properly commented with `#'`, and request the `github_document`. Here's the whole script again:
Drawing on the workflow tips in [Rmd test drive](#rmd-test-drive), let's add some YAML frontmatter, properly commented with `#'`, and request `github_document` as the output format.
Here's the whole script again:

```{r augment-demo-code, include = FALSE}
demo_code <- c(
"#' ---",
"#' title: \"R scripts can be rendered!\"",
"#' author: \"Jenny Bryan\"",
"#' date: \"April 1, 2014\"",
"#' output: github_document",
"#' ---",
"#'",
Expand All @@ -99,12 +113,14 @@ writeLines(demo_code, fs::path(va_home, "render-r-script-demo.R"))

Behind the scenes here we have used `rmarkdown::render()` to render this script and you can go [visit it on GitHub](https://github.com/jennybc/happy-git-with-r/blob/master/render-r-script-demo.md).

```{r render-demo-code, include = FALSE, error = TRUE, eval = !as.logical(Sys.getenv("TRAVIS", unset = "FALSE"))}
## render must happen elsewhere, othewise bookdown yaml clobbers doc yaml
## this is, in fact, why we're working below session temp
```{r render-demo-code}
#| include = FALSE, error = TRUE,
#| eval = !as.logical(Sys.getenv("CI", unset = "FALSE"))
# render must happen elsewhere, otherwise bookdown yaml clobbers doc yaml
# this is, in fact, why we're working below session temp
withr::with_dir(va_home, rmarkdown::render("render-r-script-demo.R"))
## copy files back into the book
# copy files back into the book
va_files <- fs::dir_ls(va_home, recursive = TRUE)
va_files_rel <- fs::path_rel(va_files, va_home)
Expand All @@ -116,8 +132,8 @@ fig_dir_rel <- fs::path_rel(fig_dir, va_home)
if (fs::dir_exists(fig_dir_rel)) {
fs::dir_delete(fig_dir_rel)
}
## TODO: figure out why this directory is deleted in the context of local
## bookdown render
# TODO: figure out why this directory is deleted in the context of local
# bookdown render
fs::dir_copy(fig_dir, fig_dir_rel)
fs::dir_delete(va_home)
Expand Down

0 comments on commit 2ba7aa2

Please sign in to comment.