Ian
Ian

Reputation: 1166

Difference between Rscript and Rs source output when rendering rmarkdown

I have a build script that knits multiple .Rmd files into .md files, and I get different results from the following ways of invoking it:

R -e source('bin/build_script.R')

works as expected, but

Rscript bin/build_script.R

does not work as expected. The difference between the .md files produced has to do with a code chunk that has the line as(x, "Spatial"). In the first method, x is converted and everyone is happy. Invoking with Rscript causes the code chunk to return the error

Error in as(x, "Spatial"): no method or default for coercing "sfc_POINT" to "Spatial"

Do Rscript and source handle imported libraries some differently?

Here's my build script:

require(knitr)
require(yaml)
require(stringr)

config = yaml.load_file('docs/_config.yml')
render_markdown(fence_char = '~')
opts_knit$set(
    root.dir = '.',
    base.dir = 'docs/',
    base.url = '{{ site.baseurl }}/')
opts_chunk$set(
    comment = NA,
    fig.path = 'images/',
    block_ial = c('{:.input}', '{:.output}'),
    cache = FALSE,
    cache.path = 'docs/_slides_Rmd/cache/')

current_chunk = knit_hooks$get('chunk')
chunk = function(x, options) {
    x <- current_chunk(x, options)
    if (!is.null(options$title)) {
        # add title to kramdown block IAL
        x <- gsub('~~~(\n*(!\\[.+)?$)',
                  paste0('~~~\n{:.text-document title="', options$title, '"}\\1'),
                  x)
        # move figures to <div> on next slide
        x <- gsub('(!\\[.+$)', '===\n\n\\1\n{:.captioned}', x)
    } else {
        # add default kramdown block IAL to kramdown block IAL to input
        x <- gsub('~~~\n(\n+~~~)',
                  paste0('~~~\n', options$block_ial[1], '\\1'),
                  x)
        if (str_count(x, '~~~') > 2) {
            idx <- 2
        } else {
            idx <- 1
        }
        x <- gsub('~~~(\n*$)',
                  paste0('~~~\n', options$block_ial[idx], '\\1'),
                  x)
    }
    return(x)
}
knit_hooks$set(chunk = chunk)

files <- list.files('docs/_slides_Rmd')
for (f in config$slide_sorter) {
    f.Rmd <- paste0(f, '.Rmd')
    if (f.Rmd %in% files) {
        f.md <- paste0(f, '.md')
        knit(input = file.path('docs/_slides_Rmd', f.Rmd),
             output = file.path('docs/_slides', f.md))
    }
}

Upvotes: 3

Views: 275

Answers (1)

Dirk is no longer here
Dirk is no longer here

Reputation: 368409

It is an old "feature" and worthy of a FAQ entry: Rscript, in its eternal wisdom does not load the methods package which comes with Base R and is needed to properly cope with S4 classes.

Just add one line library(methods) to your script and all should be good.

Or use littler instead of Rscript which does load it :)

Upvotes: 8

Related Questions