The write2*()
functions were designed as an alternative
to SAS’s ODS
procedure for useRs who want to save R
Markdown tables to separate Word, HTML, or PDF files without needing
separate R Markdown programs.
There are three shortcut functions for the most common output types:
HTML, PDF, and Word. Each of these three functions calls
write2()
, an S3 function which accepts many file output
types (see the help pages for rmarkdown::render()
). Methods
have been implemented for tableby()
,
modelsum()
, and freqlist()
, but also
knitr::kable()
, xtable::xtable()
, and
pander::pander_return()
.
The two most important things to recognize with write2()
are the following:
Which function is being used to output the object. Sometimes the
write2
functions use summary()
, while other
times they will use print()
. The details for each object
specifically are described below.
How the ...
arguments are passed. To change the
options for the summary-like or print-like function, you can pass named
arguments which will in turn get passed to the appropriate function.
Details for each object specifically are described below.
arsenal
is piping-compatible!
The write2*()
functions are probably the most useful
place to take advantage of the magrittr
package’s piping
framework, since commands are often nested several functions deep in the
context of write2*()
. Piping also allows the
arsenal
package to become a part of more standard analysis
pipelines; instead of needing to write separate R Markdown programs,
intermediate analysis tables and output can be easily incorporated into
piped statements.
This vignette will sprinkle the foward pipe (%>%
)
throughout as a hint at the power and flexibility of
arsenal
and piping.
arsenal
Objectstableby
For tableby
objects, the output function in
write2()
is summary()
. For
summary.tableby
objects, the output function is
print()
. For available arguments, see the help pages for
summary.tableby()
. Don’t use the option
text = TRUE
with the write2
functions.
mylabels <- list(sex = "SEX", age ="Age, yrs")
tab1 <- tableby(arm ~ sex + age, data=mockstudy)
write2html(
tab1, paste0(tmpdir, "/test.tableby.html"), quiet = TRUE,
title = "My test table", # passed to summary.tableby
labelTranslations = mylabels, # passed to summary.tableby
total = FALSE # passed to summary.tableby
)
modelsum
For modelsum
objects, the output function in
write2()
is summary()
. For
summary.modelsum
objects, the output function is
print()
. For available arguments, see the help pages for
summary.modelsum()
. Don’t use the option
text = TRUE
with the write2
functions.
tab2 <- modelsum(alk.phos ~ arm + ps + hgb, adjust= ~ age + sex, family = "gaussian", data = mockstudy)
write2pdf(
tab2, paste0(tmpdir, "/test.modelsum.pdf"), quiet = TRUE,
title = "My test table", # passed to summary.modelsum
show.intercept = FALSE, # passed to summary.modelsum
digits = 5 # passed to summary.modelsum
)
freqlist
For freqlist
objects, the output function in
write2()
is summary()
. For
summary.freqlist
objects, the output function is
print()
. For available arguments, see the help pages for
summary.freqlist()
.
comparedf
For comparedf
objects, the output function in
write2()
is summary()
. For
summary.comparedf
objects, the output function is
print()
.
knitr::kable()
For objects resulting from a call to kable()
, the output
function in write2()
is print()
. There aren’t
any arguments to the print.knitr_kable()
function.
xtable::xtable()
For xtable
objects, the output function in
write2()
is print()
. For available arguments,
see the help pages for print.xtable()
.
mockstudy %>%
head() %>%
xtable::xtable(caption = "My xtable") %>%
write2pdf(
paste0(tmpdir, "/test.xtable.pdf"), quiet = TRUE,
comment = FALSE, # passed to print.xtable to turn off the default message about xtable version
include.rownames = FALSE, # passed to print.xtable
caption.placement = "top" # passed to print.xtable
)
To make an HTML document, use the print.xtable()
option
type = "html"
.
mockstudy %>%
head() %>%
xtable::xtable(caption = "My xtable") %>%
write2html(
paste0(tmpdir, "/test.xtable.html"), quiet = TRUE,
type = "html", # passed to print.xtable
comment = FALSE, # passed to print.xtable to turn off the default message about xtable version
include.rownames = FALSE, # passed to print.xtable
caption.placement = "top" # passed to print.xtable
)
User beware! xtable()
is not compatible with
write2word()
.
pander::pander_return()
Pander is a little bit more tricky. Since
pander::pander()
doesn’t return an object, the useR should
instead use pander::pander_return()
. For this (and for all
character vectors), the the output function in write2()
is
cat(sep = '\n')
.
To output multiple tables into a document, simply make a list of them and call the same function as before.
mylist <- list(
tableby(sex ~ age, data = mockstudy),
freqlist(table(mockstudy[, c("sex", "arm")])),
knitr::kable(head(mockstudy))
)
write2pdf(mylist, paste0(tmpdir, "/test.mylist.pdf"), quiet = TRUE)
One neat side-effect of this function is that you can output text and headers, etc. The possibilities are endless!
mylist2 <- list(
"# Header 1",
"This is a small paragraph introducing tableby.",
tableby(sex ~ age, data = mockstudy),
"<hr>",
"# Header 2",
"<font color='red'>I can change color of my text!</font>"
)
write2html(mylist2, paste0(tmpdir, "/test.mylist2.html"), quiet = TRUE)
In fact, you can even recurse on the lists!
It may be useful at times to write output that would normally be
copied from the terminal. The default method for write2()
does this automatically. To output the results of
summary.lm()
, for example:
lm(age ~ sex, data = mockstudy) %>%
summary() %>%
write2pdf(paste0(tmpdir, "/test.lm.pdf"), quiet = TRUE)
The verbatim()
function is another option to explicitly
alert write2()
to do this. This becomes particularly
helpful to overrule existing S3 methods.
For example, suppose you wanted to just print a tableby object (as if it were to print in the terminal):
tab4 <- tableby(arm ~ sex + age, data=mockstudy)
write2html(verbatim(tab4), paste0(tmpdir, "/test.print.tableby.html"), quiet = TRUE)
Or suppose you wanted to print a character vector (as if it were to print in the terminal):
chr <- paste0("MyVector", 1:10)
write2pdf(verbatim(chr), paste0(tmpdir, "/test.character.pdf"), quiet = TRUE)
Note that you can combine multiple objects in one call:
You can add a YAML header to write2()
output using the
yaml()
function.
mylist3 <- list(
yaml(title = "Test YAML Title", author = "My cool author name"),
"# Header 1",
"This is a small paragraph introducing tableby.",
tableby(sex ~ age, data = mockstudy)
)
write2html(mylist3, paste0(tmpdir, "/test.yaml.html"), quiet = TRUE)
In fact, all detected YAML pieces will be moved as the first output, so that the above code chunk gives the same output as this one:
It is now possible to add code chunks to the output
.Rmd
:
mylist5 <- list(
"# What is 1 + 2?",
code.chunk(a <- 1, b <- 2),
code.chunk(a + b, chunk.opts = "r echo=FALSE, eval=TRUE")
)
write2html(mylist5, paste0(tmpdir, "/test.code.chunk.html"), quiet = TRUE)
This allow flexibility to create objects on-the-fly, to read in saved
objects to the temporary .Rmd
, etc. The possibilities are
endless!
This is easily accomplished by using the argument
quiet = TRUE
(passed to the
rmarkdown::render()
function).
.Rmd
file?This is easily accomplished by using the option
keep.rmd = TRUE
.
This is easily accomplished by using the option
render. = FALSE
. Note that this will then default to
keep.rmd = TRUE
.
One can simply abuse the list S3 method for
write2()
!
write2word()
,
write2html()
, or write2pdf()
?You can pass arguments to the format functions used behind the scenes.
write2html(
knitr::kable(head(mockstudy)), paste0(tmpdir, "/test.kable.theme.html"),
quiet = TRUE, # passed to rmarkdown::render
theme = "yeti" # passed to rmarkdown::html_document
)
See the help pages for rmarkdown::word_document()
,
rmarkdown::html_document()
, and
rmarkdown::pdf_document()
.
This can be done using the generic write2()
function.
The last argument in the function can be another format specification.
For details on the acceptable inputs, see the help page for
write2()
.
You can do this pretty easily with the yaml()
function:
There are now write2()
methods for the summary objects
of arsenal
functions. This allows you to specify a title
for each table:
mylist6 <- list(
summary(tableby(sex ~ age, data = mockstudy), title = "A Title for tableby"),
summary(modelsum(age ~ sex, data = mockstudy), title = "A Title for modelsum"),
summary(freqlist(~ sex, data = mockstudy), title = "A Title for freqlist")
)
write2pdf(mylist6, paste0(tmpdir, "/test.multiple.titles.pdf"))
write2()
not working in R Markdown/R
Studio?It’s possible that a global option in R Studio is preventing the tables from rendering. Consider turning off (i.e., unchecking) the option Tools > Global Options > R Markdown > Show output inline for all R Markdown documents.
arsenal
Objects
.Rmd
file?write2word()
,
write2html()
, or write2pdf()
?write2()
not working in R Markdown/R Studio?