conjugateprior

R Markdown to other document formats

Perhaps you have a file written in Markdown with embedded R of the kind that RStudio makes so nice and easy but you'd like a range of output formats to keep your collaborators happy. Say latex, pdf, html and MS Word. Here's what you might do

I shall imagine your file is called doc.Rmd

Install pandoc on your machine. (If you're on Windows you can also use Tal Galili's handy install.pandoc function described here).

First, install the knitr package. From within R

install.packages('knitr')

Then save the following code into a file. I shall imagine you called it rmd.R

require(knitr)
require(tools)

rmd.convert <- function(fname,
                        output=c('latex', 'word', 'html', "pdf")){
  ## Thanks to Robert Musk for helpful additions to make this
  ## run better on Windows

  thedir <- file_path_as_absolute(dirname(fname))
  thefile <- (basename(fname))

  create_latex <- function(f){
    knit(f, 'tmp-outputfile.md')
    newname <- paste0(file_path_sans_ext(f), ".tex")
    mess <- paste('pandoc -f markdown -t latex -s -o',
              shQuote(newname), "tmp-outputfile.md")
    system(mess)
    cat("The Latex file is", file.path(thedir, newname), 
        "\nIf transporting do not forget to include the folder",
        file.path(thedir, "figure"), "\n")

    mess <- paste('rm tmp-outputfile.md')
    system(mess)
  }

  create_word <- function(f){
    knit(f, 'tmp-outputfile.md');
    newname <- paste0(file_path_sans_ext(f),".docx")
    mess <- paste('pandoc -f markdown -t docx -o', shQuote(newname), 
                  "tmp-outputfile.md")
    system(mess)
    cat("The Word (docx) file is", file.path(thedir, newname), "\n")
    mess <- paste('rm tmp-outputfile.md')
    system(mess)
  }

  create_html <- function(f){
    knit2html(f)
    cat("The main HTML file is", file.path(thedir,
        paste0(file_path_sans_ext(f), ".html")), 
        "\nIf transporting do not forget to include the folder",
        file.path(thedir, "figure"), "\n")
  }

  create_pdf <- function(f){
    knit(f, 'tmp-outputfile.md');
    newname <- paste0(file_path_sans_ext(f),".pdf")
    mess <- paste('pandoc -f markdown -o', shQuote(newname),
              "tmp-outputfile.md")
    system(mess)
    cat("The PDF file is", file.path(thedir, newname), "\n")
    mess <- paste('rm tmp-outputfile.md')
    system(mess)
  }

  origdir <- getwd()  
  tryCatch({
    setwd(thedir) ## put us next to the original Rmarkdown file
    out <- match.arg(output)
    switch(out,
           latex=create_latex(thefile),
           html=create_html(thefile),
           pdf=create_pdf(thefile),
           word=create_word(thefile))
  }, finally=setwd(origdir))
}

Now, at the R console, source the file to get access to the rmd.convert function it defines

source('rmd2.R')

and apply rmd.convert to your source document

rmd.convert('doc.Rmd', 'html') ## for a web page
rmd.convert('doc.Rmd', 'latex') ## for a latex document
rmd.convert('doc.Rmd', 'pdf') ## for a pdf document
rmd.convert('doc.Rmd', 'word') ## for a word document

If the function runs correctly then the last line of output will tell you what your new output file is called. The resulting document and any generated folders will land next to (that is, in the same folder as) the original file.

The latex output option requires Latex to be installed on your machine, obviously. Less obviously, so does the pdf option. If you want other formats supported by pandoc, then just add a create_ function in the style of the existing ones and add it to the function's output parameter list and to the switch statement at the bottom.

Archived article and comments

From the Internet Archive