15

Is there a way to easily turn a data frame into a Word table via rmarkdown?

If I use rmarkdown in RStudio to create a Word document I get a nicely printed table but it is then not recognised as a Word-table. Can it be done at all?

   ```{r}
   name_of_df
   ```
erc
  • 10,113
  • 11
  • 57
  • 88
  • 1
    I'm not sure about rmarkdown, but you can write to Word format using the rtf package: http://cran.r-project.org/web/packages/rtf/index.html – Thomas Aug 21 '14 at 12:18

3 Answers3

27

EDIT: ReporteRs is still maintained but will not evolve anymore. Use officer and flextable instead :

library(officer)
library(flextable)
library(magrittr)

# Create flextable object
ft <- flextable(data = mtcars) %>% 
  theme_zebra %>% 
  autofit
# See flextable in RStudio viewer
ft

# Create a temp file
tmp <- tempfile(fileext = ".docx")

# Create a docx file
read_docx() %>% 
  body_add_flextable(ft) %>% 
  print(target = tmp)

# open word document
browseURL(tmp)

END EDIT

Hi you can also try package ReporteRs to turn a data.frame into a Word table, the function to do it is FlexTable :

library(ReporteRs)
library(magrittr)

docx( ) %>% 
  addFlexTable( mtcars %>%
                  FlexTable( header.cell.props = cellProperties( background.color =  "#003366" ),
                             header.text.props = textBold( color = "white" ),
                             add.rownames = TRUE ) %>%
                  setZebraStyle( odd = "#DDDDDD", even = "#FFFFFF" ) ) %>%
  writeDoc( file = "exemple.docx" )

# open the Word document
browseURL("exemple.docx")

enter image description here

With markdown, i think this work only with HTML :

---
title: "HTML table"
output: html_document
---

```{r, results='asis'}
library(ReporteRs)
tabl = FlexTable( mtcars,
                  header.cell.props = cellProperties( background.color = "#003366" ),
                  header.text.props = textBold( color = "white" ),
                  add.rownames = TRUE )
tabl = setZebraStyle( tabl, odd = "#DDDDDD", even = "#FFFFFF" )
cat(as.html(tabl))
```

Here an other example on how to create a word document with ReporteRs :

library(ReporteRs)
# Create a docx object
doc = docx()
# add a document title
doc = addParagraph( doc, "A FlexTable example", stylename = "TitleDoc" )
# add a section title
doc = addTitle( doc, "How to turn a data.frame into a Word table", level = 1 )
# some text
doc = addParagraph( doc, "We use the mtcars dataset as example.", stylename = "DocDefaults" )
# add a table
MyFTable = FlexTable( data = mtcars[1:10, ], add.rownames = TRUE )
# format body content
MyFTable[3:4, "cyl"] = cellProperties( background.color = "red" )
MyFTable["Valiant", ] = cellProperties( background.color = "blue" )
doc = addFlexTable(doc, MyFTable)
# write the doc
writeDoc( doc, file = "exemple.docx" )
# open the Word doc
browseURL("exemple.docx")

enter image description here

For more example you can visit http://davidgohel.github.io/ReporteRs/word.html

Victorp
  • 13,636
  • 2
  • 51
  • 55
  • why did you add the browseURL call at the end of the ReporeRs portion? Why not open the Word document and use the table in it? Also, using the same package, do you know how to create a title page neatly? Thanks – lawyeR Aug 24 '14 at 12:04
  • 3
    The purpose of `browseURL` is only to open the Word doc from R. I add an other example with a title, if it helps. – Victorp Aug 24 '14 at 18:29
4

Here is a very low-tech (and fast) way to do it

source("http://michael.hahsler.net/SMU/EMIS7332/R/copytable.R") 

and run the example

copytable(summary(iris))

now copy&paste and you are done!

Just for reference, here is also the source code for the copytable function:

library(xtable)

copytable <- function(x, ...) {
  f <- tempfile(fileext=".html")
  print(xtable(x, ...), "html", file = f)
  browseURL(f)
}
Michael Hahsler
  • 2,965
  • 1
  • 12
  • 16
  • Could you provide the source code here in your answer instead? – coip Aug 29 '17 at 20:59
  • 1
    @copi Just go to http://michael.hahsler.net/SMU/EMIS7332/R/copytable.R for the source code. – Michael Hahsler Aug 30 '17 at 23:19
  • I did, but many organizations' Internet filtering systems block personal sites, so I thought it would be better for future readers if the complete solution was available here at Stack Overflow rather than an external site some people may not be able to access. – coip Aug 30 '17 at 23:26
2

You can use the rmarkdown and knitr packages. Here is an example function, where df is the data.frame, output_file is the output file name and output_dir the output folder. Extra named argument are sent to rmarkdown::render:

df2word <- function(df, output_file = "table.doc", output_dir = ".", ...) {
  f <- tempfile(fileext =".Rmd" )
  cat(file = f, '```{r, echo = FALSE}
                  knitr::kable(df)
                 ```', append = TRUE)
  rmarkdown::render(f, output_file = output_file, output_dir = output_dir, ...)
  unlink(f)
  file.path(output_dir, output_file)
}

out <- df2word(mtcars)
browseURL(out)

Of course you can adapt the code to be more flexible.

It is though flexible enough to allow you to extract other formats too, e.g. html:

out <- df2word(mtcars, output_file = "table.html")
browseURL(out)

or pdf:

out <- df2word(mtcars, output_file = "table.pdf", output_format = rmarkdown::pdf_document())
browseURL(out)
alko989
  • 7,688
  • 5
  • 39
  • 62