How to print an html table to pdf? - r

Consider this simple example
library(knitr)
library(kableExtra)
dt <- mtcars[1:5, 1:4]
# HTML table
kable(dt, format = "html", caption = "Demo Table") %>%
kable_styling(bootstrap_options = "striped",
full_width = F) %>%
add_header_above(c(" ", "Group 1" = 2, "Group 2[note]" = 2)) %>%
add_footnote(c("table footnote"))
Here I want a very simple thing. To print this table in a pdf (possibly in a pipe-able way). I want the table to look exactly like this.
I know this is html, but arent we able to print html pages to pdf in chrome? There has to be a way (I hope). I do not want to deal with latex and I do not want to create an rnotebook document. The rendering has to come from my bare .R script. Is that impossible?
Any ideas?
Thanks!

Here is a solution to part of your problem of generating a table in pdf form. You will need to tweak the styling of your table in xtable in order to get the zebra stripe you want and merged columns. Generally speaking conversion from html to pdf is not so straightforward, so a better solution is to use LaTeX to generate your table in the first place (I know you didn't want LaTeX, but at least this is compiled to pdf with R and xtable does the hard work):
library(xtable)
dt <- mtcars[1:5, 1:4]
filename <- tempfile(fileext = ".tex")
capture.output(print(xtable(dt)), file = filename)
foo <- readLines(filename)
writeLines(c("\\documentclass[hidelinks]{article}",
"\\begin{document}",
foo,
"\\end{document}"),
con = filename)
tools::texi2dvi(filename, pdf = TRUE)
You should have a look at https://cran.r-project.org/web/packages/xtable/vignettes/xtableGallery.pdf to get your styling the way you want it. Good luck.
Edit:
Seems you can use kabelExtra too:
library(knitr)
library(kableExtra)
dt <- mtcars[1:5, 1:4]
# LaTeX table
a <- kable(dt, format = "latex", caption = "Demo Table") %>%
kable_styling(bootstrap_options = "striped",
full_width = F) %>%
add_header_above(c(" ", "Group 1" = 2, "Group 2[note]" = 2)) %>%
add_footnote(c("table footnote"))
filename <- tempfile(fileext = ".tex")
capture.output(a, file = filename)
foo <- readLines(filename)
writeLines(c("\\documentclass[hidelinks]{article}",
"\\begin{document}",
foo,
"\\end{document}"),
con = filename)
tools::texi2dvi(filename, pdf = TRUE)

Related

How to handle the overlay of kable output with page number?

I use kbl() function, in a rnw file that I compile in a pdf with knitr, to make a table starting from a dataframe. I use kableExtra option scale_down to adapt the table size to page size. It works fine but the table overlay with the page number of my pdf output. I'd like to know what's the best way to handle this type of problem. Thanks in advance for the help.
You could add some Latex code that puts the tabular environment into a box and resizes the content. Below is an example using \resizebox
Here's tab, a LaTex table with Gaussian random numbers generated by kable:
```{r, message = F, warning=F}
library(knitr)
library(tidyverse)
library(kableExtra)
ncol <- 10
nrow <- 30
df <- map_dfc(1:ncol, ~ data.frame(round(rnorm(nrow), 2))) %>%
set_names(letters[1:ncol])
tab <- kbl(df, format = "latex")
```
And here's how to resize it by text height/width using resizebox (see this post on tex.stackexchange for details on how the scaling works)
```{r, results='asis'}
cat(
"\\begin{table}
\\centering
\\resizebox*{\\textwidth}{\\dimexpr\\textheight-2\\baselineskip\\relax}{%",
tab,
"\n}
\\end{table}"
)
```
Result for the 30x10 table
Let's double rows and columns (ncol <- 20; nrow <- 60)
Result for 60x20 table.
I have three suggestions. The first one is maybe set your table to the next page using \newpage in your Rmarkdown code which is latex code. The second option is maybe set latex_options="HOLD_position" in your Kable_styling function. This will set the table at a certain place which maybe could help your problem. The third option is using 'longtable = TRUE` which means that the table continues on the next page. Here is the code for option one and two with:
```{r}
library(knitr)
library(tidyverse)
library(kableExtra)
df <- data.frame(x = 1:10, y = 11:20)
kable(df) %>%
kable_styling(latex_options = "HOLD_position")
```
\newpage
```{r}
kable(df) %>%
kable_styling(latex_options = "HOLD_position")
```
Which looks like this:
Here is the code for option three:
```{r}
library(tidyverse)
library(knitr)
library(kableExtra)
df <- data.frame(x = 1:50, y = 11:60)
kable(df, "latex", longtable = T, booktabs = T) %>%
kable_styling(latex_options = c("repeat_header"), font_size = 7)
```
Looks like this:

How to generate automatic numbering of table titles in word using knit in Rmarkdown?

I'm doing a markdown report for my work. I need the outputs in word. Although with KABLE I can place titles on my tables, they are not numbered.
What should I add to kable () or in YAML to get automatic numbering of my tables?
crude example of what I do:
table(cars$speed) %>%
as.data.frame() %>%
kable(caption = "title",digits = 0, format.args = list( decimal.mark = ",",big.mark = "."),booktabs = T) %>%
kable_styling(latex_options = c("hold_position"))
To do this you will need to use the bookdown extensions to markdown. The following is an example rmarkdown (.Rmd) file which does want you want:
---
output:
bookdown::word_document2
---
See Table \#ref(tab:myfirsttable).
```{r myfirsttable, echo = FALSE}
knitr::kable(head(cars, 3), caption = "First three rows of cars dataset")
```
See Table \#ref(tab:mysecondtable).
```{r mysecondtable, echo = FALSE}
knitr::kable(head(iris, 3), caption = "First three rows of iris dataset")
```
Once generated the word document looks like:
For more information see:
https://bookdown.org/yihui/bookdown/a-single-document.html
https://bookdown.org/yihui/bookdown/tables.html

Rotating a table in PDF output from RMarkdown with more than one page

I want to rotate a wide table in my PDF output. I came across this fantastic question, but my table is longer.
When I copy/paste one of the examples shown in that question, it works nice using RMarkdown.
library(kableExtra)
kable(iris[1:5,],
format = "latex", booktabs = TRUE) %>%
kableExtra::landscape()
However, if we remove the subsetting we see that the table exceeds the dimension of the page.
library(kableExtra)
kable(iris,
format = "latex", booktabs = TRUE) %>%
kableExtra::landscape()
So my question is very simple: how can we create as many PDF pages as needed by splitting the table in parts?
Can you try this (sorry I can't comment) :
dt <- iris
kable(dt, "latex", longtable = T, caption = "title") %>%
kable_styling(font_size = 7, latex_options = c("repeat_header"),repeat_header_text = "",
full_width = F) %>% kableExtra::landscape()
This seems to work for me.
Here's the result : pdf output
Is it what you want?

How to show and run code but don't print results in Rmarkdown knitr

When I knit the following code chunk in Rmarkdown it will print out the results as well. I just want to run and show the code. In other code chunks in the same .Rmd file this knitr syntax works...
```{r import, results = "hide"}
gs_ls()
df <- gs_title("worlds-view-of-America")
confInPres <- df %>% gs_read(ws = "Sheet1", range = cell_rows(1:38))
colnames(confInPres) <- paste("year", colnames(confInPres), sep = "_")
colnames(confInPres)[1] <- "Country"
confInTrump <- select(confInPres, Country, year_2017)
favUS <- df %>% gs_read(ws = "Sheet2", range = cell_rows(1:38))
```
Take a look here.
If you want to show the code, use echo=TRUE.

R, Latex and RMarkdown: table() input for xtable() missing column and row labels?

I am trying to create a pretty LaTeX table where the names of the row and column variables of a table are included when using the xtable library.
MWE:
```{r results="asis"}
test <- data.frame(Apples=c(1,2,3), Oranges=c(4,5,6), Watermelons=c(7,8,9))
testxtab <- xtable(with(test,table(Apples,Oranges)))
print(testxtab, comment=FALSE)
```
The result is a LaTeX table that is missing the "Apples" and "Oranges" labels. How do I include them?
I'm sure you could adapt this to xtable, but here's one approach you can take using pixiedust. (It isn't a very elegant solution, but given the structure of the table object, I'm not sure elegant is an option).
library(pixiedust)
obj <- with(test, table(Apples, Oranges))
dimnames <- names(attr(obj, "dimnames"))
head <-
rbind(c("", dimnames[2], rep("", ncol(obj) - 1)),
c(dimnames[1], colnames(obj))) %>%
as.data.frame(stringsAsFactors = FALSE)
body <- cbind(rownames(obj), obj) %>%
as.data.frame(stringsAsFactor = FALSE)
dust(body) %>%
redust(head, part = "head") %>%
sprinkle(rows = 1,
cols = 2:4,
merge = TRUE,
part = "head") %>%
medley_bw() %>%
sprinkle_print_method("latex")

Resources