Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git
# R

This chapter describes how to use R within the application to add dynamic
content to documents. It covers integration basics, environment setup, creating
visualizations, working with external data, and using YAML variables in R code.

## Integration

R integration allows embedding R code directly into documents for dynamic
content generation, such as statistical analysis and data plots. The
application supports R Markdown (`.Rmd`) files, where R code can be executed
inline or in chunks to produce results, including numerical outputs and
visualizations. KeenWrite's R integration is largely compatible with the
syntax for pandoc / knitr.

## Environment

Setting up the R environment involves configuring scripts and directories to
load custom functions and manage file locations. This ensures R code runs
smoothly within the application.

### Bootstrapping

A bootstrap script loads custom R libraries or functions at startup. Complete
the following steps to call an R function from your own library:

1. Click **File → New** to create a new file.
1. Click **File → Save As**.
1. Browse to your home directory.
1. Set **Name** to: `library.R`.
1. Click **Save**.
1. Set the contents to:

    ``` r
    sum <- function( a, b ) {
      a + b
    }
    ```

1. Click the **Save** icon.
1. Click **R → Script**.
1. Set the **R Startup Script** contents to:

   ``` r
   source( 'library.R' );
   ```

1. Click **OK**.
1. Create a new file.
1. Set the contents to:

   ``` r
   `r#sum( 5, 5 )`
   ```

1. Save the file as `math.R`.

The preview tab shows the result of calling the `sum` function:

> 10.0

This shows how the bootstrap script can load `library.R`, which defines a `sum`
function that is called by name in the Markdown document.

### Working directory

The working directory determines where R searches for source files. Accomplish
this as follows:

1. Click **R → Directory**.
1. Set **Directory** to a different directory.
1. Click **OK**.
1. Create the directory if it does not exist.
1. Move `library.R` into the directory.
1. Append a new function to `library.R` as follows:

   ``` r
   mul <- function( a, b ) {
     a * b
   }
   ```

1. Click **R → Script**.
1. Set the **R Startup Script** contents to:

   ``` r
   setwd( v$application$r$working$directory );
   source( "library.R" );
   ```

1. Change `math.Rmd` to:

   ``` r
   `r#mul( 5, 5 )`
   ```

1. Close the file `math.Rmd`.
1. Confirm saving the file when prompted.
1. Re-open `math.Rmd`.

The preview tab shows:

> 25.0

Calling `setwd` using `v$application$r$working$directory` changes the working
directory where the R engine searches for source files.

## Data visualizations

Data plots can be generated using R. First, create a new file:

1. Start the application.
1. Click **File → New** to create a new file.
1. Click **File → Save As**.
1. Set **Name** to: `plot.Rmd`
1. Click **Save**.

Setting the file name extension tells the application what processor to use
when transforming the contents. To insert visual content, such as a plot, use
the knitr-compatible syntax of ` ```{r}` and ` ``` ` to enclose multi-line R
snippets:

    ```{r}
    x <- seq( 0, 2 * pi, length.out=100 )
    y <- sin( x )
    plot( x, y, type="l" )
    ```

## Variable definitions

Variables provide a way to define reusable values that can be referenced
dynamically within R code. To see how variable definitions work in R, try the
following:

1. Create a new file.
1. Change the contents to (use spaces to indent, not tabs):

   ``` yaml
   project:
     title: Project Title
     author: Author Name
   ```

1. Save the file as `definitions.yaml`.
1. Click **File → Open**.
1. Set **Source Files** to **Variable Files**.
1. Select `definitions.yaml`.
1. Click **Open**.
1. Open `math.Rmd` if it is not already open.
1. Type: `je`
1. Press [Ctrl+Space]{.kbd}.

The editor inserts the following text (matches `je` against Pro**je**ct):

``` r
`r#x( v$project$title )`
```

The preview tab shows:

> 25.0

This is because the application inserts variable reference names based on the
type of file being edited. By default, the R engine does not have a function
named `x` defined. The `x` function performs fail-safe string conversions.

Continue as follows:

1. Click **R → Script**.
1. Append the following:

   ``` r
   x <- function( s ) {
     tryCatch( {
       r = eval( parse( text = s ) )

       ifelse( is.atomic( r ), r, s );
     },
     warning = function( w ) { s },
     error = function( e ) { s } )
   }
   ```

1. Click **OK**.
1. Close and re-open `math.Rmd`.

The preview tab shows:

> 25.0
>
> Project Title

The `x` function attempts to evaluate the expression defined by the variable.
This means that the variables can also include expressions that R is capable of
evaluating.

Externally defined variables are assigned to the `v` object in R code.  This
allows dereferencing them using a `$`-separated string. The moustache and
dot-separated notation also works (e.g., `{{project.title}}`), but better to be
consistent.

## Comma-separated values

Many R functions are included, like one that converts comma-separated values to
tables. Consider travel fares saved as `fares.csv` alongside the main document:

``` csv
Distance, "Fare ($)"
26.7,         73.75
16.4,         56.00
32.7,         83.25
77.0,        190.50
```

Call `csv2md` using a path relative to the R working directory, such as:

``` r
`r# csv2md( '../docs/fares.csv' );`

:: Taxi fares vs. distance
```

Convert the document from R Markdown to Markdown from the command line:

``` bash
keenwrite.bin \
  --r-script="${HOME}/writing/R/bootstrap.R" \
  --r-dir="${HOME}/writing/R" \
  -i 00.Rmd \
  -o 00.md
```

The output file, `00.md`, contains the result from running the function:

``` markdown
|Distance| Fare ($)|
|:---|---:|
|26.7| 73.75|
|16.4| 56.00|
|32.7| 83.25|
|77|190.50|
|Totals|481.65|

:: Taxi fares vs. distance
```

By isolating the data to an external file, it is possible to update the file
and rebuild the document to insert the latest values.