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

  1. Install pandoc http://code.google.com/p/pandoc/downloads/list on your machine. (If you’re on Windows you can also use Tal Galili’s handy install.pandoc function described here).
  2. Install the knitr package. From within R
    install.packages('knitr')
  3. Save the following code into a file. I shall imagine you called it rmd.R
    rmd.convert <- function(fname, output=c('latex', 'word', 'html', "pdf")){
      ## Thanks to Robert Musk for helpful additions to make this run better on Windows
    
      require(knitr)
      require(tools)
      
      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))
      
    }
    
  4. Within R, source the file to get access to the rmd.convert function it defines
    source('rmd2.R')
  5. 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.

11 thoughts on “R Markdown to other document formats

    1. Dan

      Hi,

      This works for html but i get the following error for the word file.
      pandoc.exe: tmp-outputfile.md;: openFile: does not exist (No such file or directory)

      Could it be that i require latex?

      Thanks
      Dan

      Reply
      1. Will Post author

        Hmmm. As you can see from my code, knitr (an R package) does the HTML conversion and pandoc does the others. This suggests to me that your pandoc setup is not quite right – or that my R code fails to appreciate something about Windows which is not unlikely. In any case I suggest you first make sure that you can use pandoc to create word documents outside of R, that is: directly via the console (a.k.a. CMD on Windows). For this, the simplest examples on the pandoc homepage will suffice. If they work then we can have a look at what’s going wrong on the R side of things.

        Reply
  1. Ana Guedes

    Hi,

    I’ve been struggling with conversion of Rmd files to pdf.
    I have tried your approach and I get the following error:

    Warning message:
    running command ‘pandoc -f markdown -o “file.pdf” tmp-outputfile.md; rm tmp-outputfile.md’ had status 1

    Do you know what is going wrong?

    Thanks

    Reply
    1. Will Post author

      Non-zero status indicates something went wrong in the pandoc part of things. The two basic possibilities are that the file does not exist under that name or that pandoc has some problem with its content. The best way to find out what’s happening is to run the same command yourself directly. Indeed I’d recommend first making sure that pandoc works on small and simple files, and then figuring out what is problematic about the one you’re trying to convert. You can see above that the R function only constructs a possible command line called ‘mess’, so it should be straightforward to adjust that to run pandoc over your own file. The pandoc homepage has examples.

      You might also install RStudio, which can do this kind of .Rmd conversion too. Not only might your file work there, but it’s also possible that you’ll get a more informative error message if it doesn’t.

      Reply
    2. Kent

      Try using the -s or –standalone option in your command line. You might have to change the function so it includes that option.

      Reply
  2. Eddie

    This excellent and the kind of thing we have been waiting for. It just makes life so easy for R users. well done.

    Reply
  3. Robert Musk

    This is a great idea. Thanks for your work. It wasn’t running pandoc for me though. I had to change the system call to separate the pandoc process from the file removal. For example:

    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)
    }

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>