Table Gets Cut Off When Knitting to PDF - r

I am in the process of creating a table 1 for my work, but when I knit my R Markdown file to PDF, some of the table gets cut off. Can I modify my code to either knit it landscape or not have half the table cut off?
table_1 <- CreateTableOne(
vars = vars,
data = Cambodia,
factorVars = fvars,
test = FALSE,
)
tab1 <- kable(
print(table_1,
showAllLevels = TRUE,
printToggle = FALSE,
noSpaces = TRUE,
catDigits = 1,
contDigits = 1),
caption = paste(
"Baseline Characteristics of xyz."
)
)
print(tab1)

You can use kable_styling from the kableExtra package. The option would be latex_options="scale_down". You can use font sizes as well, please see https://haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf

Related

How can I add a fontawesome icon to a table in Rmarkdown?

I'm looking for tidy way to add a hyperlink incorporating a fontawesome icon to an Rmarkdown table (kable) — for incorporation in an html bookdown page.
In other parts of my document, I've used the icon package, to render a hyperlinked fontawesome icon (outside of a table) using standard markdown syntax, e.g.:
`r icon::fa("file-pdf", size = 5)](https://www.google.com/){target="_blank"}`
But this approach doesn't work when I've attempted to incorporate it as part of a kable.
```{r}
library(icon)
library(knitr)
library(tidyverse)
## note this code throws the following error: Error in
## as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors =
## stringsAsFactors) : cannot coerce class "c("knit_asis",
## "knit_icon")" to a data.frame
link_location <- "www.google.com"
data_test_1 <- data.frame(
file = c('Version 1', 'Version 2', 'Version 3'),
last_updated = Sys.Date(),
pdf_logo = icon::fa("file-pdf")) %>%
mutate(pdf_logo = cell_spec(pdf_logo,
link = link_location)) %>%
kable("html", escape = F, align = "c")
data_test_1
```
So far I've come up with a workaround that involves downloading the .svg file from the fontawesome website and adding it as an image. It works... sort of, but I would prefer to have the ability to change the size of the icon and make it more easily reproducible.
This is the code for my current workaround.
```{r fontawesome_table ='asis'}
library(tidyverse)
library(kableExtra)
## download svg from location manually
https://fontawesome.com/icons/r-project?style=brands
data_test_2 <- data.frame(
file = c('Version 1', 'Version 2', 'Version 3'),
last_updated = Sys.Date(),
R_logo = "![](r-project-brands.svg)") %>%
mutate(R_logo = cell_spec(R_logo, link = "https://cran.r-
project.org/")) %>%
kable("html", escape = F, align = "c")
data_test_2
```
Which produces this output...
Does anyone have any ideas for how I could either, adjust the size the icon in the table, or call the icon from another package/css to create a more tidy solution?
Here is a way using the fontawesome package instead. I also had to use a custom link building function:
```{r, echo = F, message=F, warning=F}
library(fontawesome)
library(knitr)
library(tidyverse)
library(kableExtra)
## note this code throws the following error: Error in
## as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors =
## stringsAsFactors) : cannot coerce class "c("knit_asis",
## "knit_icon")" to a data.frame
link_location <- "www.google.com"
addLink <- function() {
paste0("", as.character(fa("file-pdf")), "")
}
data_test_1 <- data.frame(file = c('Version 1', 'Version 2', 'Version 3'),
last_updated = Sys.Date(),
pdf_logo = addLink())
kable(data_test_1, escape = F, align = "c")
```
Another solution is the icons package. With icons you cannot only use fontawesome but several icon packages incl. Material icons, e.g.
Install it with devtools::install_github("mitchelloharawild/icons").
Download the font you want to use, here: download_fontawesome().
Now access the icon with either fontawesome("rocket", style = "solid") or icons::fontawesome$solid$rocket.
In an Rmarkdown document like this:
```{r icon-chunk}
fontawesome("rocket", style = "solid")
```
or inline like this
`r icons::fontawesome("rocket", style = "solid")`
In some cases you may need backticks. E.g. for the R icon
fontawesome$brands$`r-project`

Space after every five rows in kable output (with booktabs option) in R Markdown document

I am using knitr::kable() to render tables as part of an R Markdown document (that itself is part of a bookdown project). In particular, the booktabs option (through setting the booktabs argument to equal TRUE) renders the table in a nice-looking way. However, I'd like for there not to be a space after every five rows.
Here, for example, is the code and how the table in the bookdown demo appears when rendered as a PDF:
knitr::kable(
head(iris, 20), caption = 'Here is a nice table!',
booktabs = TRUE
)
I'd like for the space that aappears after every five rows to not be included, but I cannot seem to find a setting in knitr::kable() that does this.
The reason why the row height is not always equal is that by default, kable inserts a \addlinespace every 5 rows when booktabs is specified as TRUE, as is shown here:
linesep = if (booktabs) c('', '', '', '', '\\addlinespace') else '\\hline'
To alter this, add linesep = "" as an argument to kable().
knitr::kable(
head(iris, 20), caption = 'Here is a nice table!',
booktabs = TRUE,
linesep = ""
)
See Get rid of \addlinespace in kable for more details.
It is also worth saying that you can play around with this option if you want to change the style. For example linesep = c("", "", "", "\\hline") would add a horizontal line every four spaces.
Based on the example above I was interested in controlling the separation. That works nicely with the following helper function. This makes it possible to control the locations of the line separation.
linesep<-function(x,y=character()){
if(!length(x))
return(y)
linesep(x[-length(x)], c(rep('',x[length(x)]-1),'\\addlinespace',y))
}
knitr::kable(
head(iris, 20), caption = 'Here is a nice table!',
booktabs = TRUE,
linesep = linesep(c(3,2,1,1,3,5,4,1))
)
Bart's answer failed to work for me on my remote server when using prettyNum() on the table and passing the output to kableExtra::kable_styling(), where it just added an column full of NAs and no linespaces. It seems to work fine on my local machine, so I can't reproduce the error.
Anyway, this alternative solution works for me (but only when passing the table to kableExtra for some reason):
linesep <- function(table, groups) {
sep_indx <- rep("", nrow(table))
sep_indx[cumsum(groups)] <- '\\addlinespace'
return(sep_indx)
}
knitr::kable(
head(iris, 20),
caption = 'Here is a nice table!',
booktabs = TRUE,
linesep = linesep(head(iris, 20), c(3, 2, 1, 1, 3, 5, 4, 1))
) %>% kableExtra::kable_styling(latex_options = c("scale_down", "HOLD_position"))
example

R Markdown Footnote in xtable

I'm having issues with a footnote not appearing under a table in my R Markdown report. Below is the code I'm using to process which does successfully but with no footnote appearing under the table.
```{r ccxtable7, results="asis", echo=FALSE}
comment <- list(pos = list(0), command = NULL)
comment$pos[[1]] <- c(nrow(indPctChgCC))
comment$command <- c(paste("\\hline\n",
"{\\footnotesize Note: * signifies number of
properties used was 35 or less.}\n", sep = ""))
print(xtable(valPctCon(indPctChgCC, indfreqCC, 35), align = "crrrrr",
label = "tab:indCC", add.to.row = comment, hline.after = c(-1,0),
caption = "Industrial Certified-Certified Percentage Change per Value Segment"))
```
indPctChCC is a 3x5 matrix of strings. Could someone help me understand why the footnote is not appearing under the table with this current code?
add.to.row (and also hline.after) are arguments of the print function, not xtable().
This should get you where you want:
print(xtable(tab, align = "crrr",
label = "tab:indCC",
caption = "Industrial Certified-Certified Percentage Change per Value Segment"),
add.to.row = comment,
hline.after = c(-1,0))

Iteratively producing latex tables in knitr

I'm working on iteratively producing LaTeX tables using knitr. All is well except I'm left with extra markup before each table. Here's a simple example, though this would ideally work as a template for more complex problems, ie different-size tables, varying data sets etc.
What can I do to get rid of the extra text before each table?
\documentclass{article}
\usepackage{setspace, relsize}
\usepackage[margin=.5in, landscape]{geometry}
\usepackage{pdfpages}
\begin{document}
<<setup, include=FALSE>>=
opts_chunk$set(echo=FALSE, warning = FALSE, message = FALSE, cache = FALSE, error = FALSE)
library("ggplot2")
library("knitr")
library("Hmisc")
mytable_function = function(mydata){
foo = as.matrix(head(mydata))
colnames(foo) = names(mydata)
rownames(foo) = c("First", "Second", "Third", "Fourth", "Fifth", "Sixth")
return(foo)
}
template <- "<<thisthing-{{i}}>>=
mytable = mytable_function(iris[iris$Species == unique(iris$Species)[i],])
latex(mytable, file = '',
title = '',
where = '!h',
caption = 'This is a table',
col.just = rep('r', ncol(mytable)))
#"
for(i in 1:3){
cat(knit(text = knit_expand(text = template, i = i, quiet = TRUE)))
}
#
\end{document}
Fwiw here's a similar question I asked a while ago but because I'm producing tables here and not figures I think this is a slightly different solution.
Print a list of dynamically-sized plots in knitr
The provided code does not match the output you presented. Actually, it produces no output whatsoever.
Step 0: Reproduce output from the question
include=FALSE on the only chunk in the document is quite fatal … replace by echo=FALSE.
The main chunk (setup) as well as the template chunk need results="asis".
message=FALSE should be a chunk option of setup. Setting it as default options within setup won't affect messages from the current chunk.
Step 1: Immediate issue
This line
cat(knit(text = knit_expand(text = template, i = i, quiet = TRUE)))
shoud be
cat(knit(text = knit_expand(text = template, i = i), quiet = TRUE))
quiet is an argument of knit, not knit_expand.
Step 2: A better solution
Although this works, it's an overly complicated overkill. The answer you linked to dynamically generated chunks because fig.height is not vectorized the way it would be required for that case. Here, we can just use a single chunk:
\documentclass{article}
\begin{document}
<<setup, echo = FALSE, results='asis', message = FALSE>>=
mytable_function = function(mydata){
foo = as.matrix(head(mydata))
colnames(foo) = names(mydata)
rownames(foo) = c("First", "Second", "Third", "Fourth", "Fifth", "Sixth")
return(foo)
}
for(i in 1:3){
mytable = mytable_function(iris[iris$Species == unique(iris$Species)[i],])
Hmisc::latex(mytable,
file = '',
title = '',
where = '!h',
caption = 'This is a table',
col.just = rep('r', ncol(mytable)))
}
#
\end{document}

Separate columns for text and code/output in Markdown

I am writing a small exercise book with Markdown. I would like to have the final output with the plots on a column and the document text on the other. Similar problems are addressed here and here. Unfortunately, they mainly desire one output per column. I would like to produce the output on a column and the text on the other. Really interesting is Docco, but it apprently shows the code output with the text.
A possible solution would be the RPres markdown horizontal rule: using ***, it creates two easy to use columns. But I do find documentation on its implementation in Markdown documents.
Here an image showing my results so far and an example of my code:
```{r setoption, cache=TRUE, warning=FALSE, message=FALSE, fig.width=12}
knitr::opts_chunk$set(cache=TRUE, warning=FALSE, message=FALSE, fig.width=4, echo = FALSE)
```
```{r, loadlibraries}
library(knitr)
library(lattice)
```
### Exercise 1 - 22/4/'16
Is the data set shown in the following figure symmetric or skewed? How many modes does this data set have?
```{r 1.1}
e1 <- rep(seq(1, 6, 1), c(6, 4, 2, 2, 4, 6))
barchart(table(e1), horizontal = FALSE, xlab = "", ylab = "Frequency")
```
**Solution:**
The data set is symmetric. Furthermore, it has two modes.
### Exercise 2 - 22/4/'16
Describe the shape of the dataset shown in the following figure.
```{r 2.1}
e2 <- rep(seq(1, 9, 1), c(6, 5, 4, 3, 2, 1, 1, 1, 1))
barchart(table(e2), ylab = "Frequency", horizontal = FALSE)
```
**Solution:**
The dataset is right skewed, also said right skewed, with one mode.
As you're asking for columns, my answer will be: table.
Using pipe_tables, figure and text can be alinged next to each other. However, this comes at a price:
The cells of pipe tables cannot contain block elements like paragraphs and lists, and cannot span multiple lines.
If this limitation is acceptable, pipe_tables provide a quite straightforward solution:
```{r img, fig.show = "hide", echo = FALSE}
library(knitr)
hist(rnorm(1000))
```
Figure|Explanation
-------------------------------|-------------------------
`r include_graphics(paste0(opts_chunk$get("fig.path"), "img-1.png"))`|Histogram of 1000 draws from a standard normal density.
Although the column headers cannot be omitted, you can leave them blank if desired.
Note that I initially suppress the plot (fig.show = "hide") and use include_graphics to include it afterwards. Otherwise, there would be a newline after the plot which disrupts the table.
(In knitr 1.12.3, include_graphics doesn't seem to work properly with inline code chunks. However, the current development version 1.12.25 works well.)
Extension
I hacked together an extension that allows to use a single chunk to generate and show the plots and some more features:
```{r setup, echo = FALSE}
library(knitr)
FigureNextToText <- function(number, # number of plot in chunk
text,
alt = "", # alternative text for image
label = opts_current$get("label"), # set explicitly when using inline!
ext = ".png",
headerL = " ", headerR = " ", # empty string confuses pandoc if only right header is set
widthL = 30, widthR = 30,
...) {
path <- fig_chunk(label = label, ext = ext, number = number, ...)
template <- "%s|%s
%s|%s
![%s](%s)|%s\r\n\r\n"
output <- sprintf(
template,
headerL, headerR,
paste0(rep("-", widthL), collapse = ""), paste0(rep("-", widthR), collapse = ""),
alt, path, text
)
return(asis_output(output))
}
```
```{r img, fig.show = "hide", echo = FALSE, results = "asis"}
library(knitr)
hist(rnorm(1000))
hist(runif(n = 1000, min = 0, max = 10))
FigureNextToText(1, text = "Histogram of draws from standard normal density.", widthL = 50, widthR = 10)
FigureNextToText(2, text = "Histogram of draws from uniform distribution.", headerR = "Explanation", alt = "Histogram 2.")
```
Some text.
`r FigureNextToText(2, text = "The same plot, this time inline.", label = "img", headerR = "Explanation", alt = "Histogram 2.")`
Some more text.
I know that the setup looks a little bit scary, but once FigureNextToText is defined, it can be called quite simply, e.g.:
FigureNextToText(2, text = "Histogram of draws from uniform distribution.", headerR = "Explanation", alt = "Histogram 2.")
Finding the correct values for widthL and widthR is somewhat cumbersome. This is because their effect depends on the number of characters in the cell, i.e. the filename of the image in the MD file and the alt text, too.

Resources