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:
I'm trying to knit a table in a large Rmarkdown document. The table represent disease levels on a farm and thus some are expressed as percentages percentages. When the disease levels are above target I would like to highlight by changing the color of the font to red. This works fine when text does not have a % label, but when I escape the % label the % label in the PDF document is always proceeded by an unwanted "". I'm a vet not a data scientist I have spent many hours on this but can't find an answer.
The original document is extremely complex pulling data from many sources to generate the current disease levels and targets using shiny input to determine various options so not possible to use code from the original document. But I have produced a very minimal reproducible example below
require(kableExtra)
require(scales)
library(knitr)
require(tidyverse)
knitr::opts_chunk$set(echo = TRUE)
MDF = data.frame(a = label_percent()(.07),b = label_percent()(.05))
MDF$a = as.character(MDF$a)
MDF$b = as.character(MDF$b)
MDF[1,] = apply(MDF[1,],2,function(f) gsub("%", "\\\\%", f))
MDF = MDF %>% mutate(a = cell_spec(a, color = ifelse(a > 6,"red","black")))
kable(MDF, "latex", escape = F, booktabs = T)
As far as I get it the issue is that the percent sign in the conditionally formatted cell gets escaped twice, once via the gsub and once via kable itself so that you end up with an additional \textbackslash() inserted in you latex code. Hence, one option to solve your issue would be to manually escape only the percent signs in the column to which you don't apply the conditional formatting:
---
title: "Untitled"
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r}
require(kableExtra)
require(scales)
library(knitr)
require(tidyverse)
MDF = data.frame(a = .07, b = .05) %>%
mutate(across(c(a, b), percent)) %>%
# Escape percent sign in column b only
mutate(across(c(b), ~ gsub("%", "\\\\%", .x))) %>%
mutate(a = cell_spec(a, color = ifelse(a > 6,"red","black")))
kable(MDF, "latex", escape = F, booktabs = T)
```
I would like to apply some latex-style formatting to column headings in a pander table in rmarkdown, knitting to pdf.
Notice in the toy document below the latex commands that work for the elements of the dataframe do not work for the headings. Specifically I would like (1) to be able to italicise some headings, (2) to be able to have headings with spaces between the letters (at the moment R automatically adds a .). However I am generally interested in how to get the headings in a dataframe to accept the same latex commands as the elements of the dataframe.
---
title: "Chapter 12: Adding to the Discrete Time Hazard Model"
output:
pdf_document: default
html_document: null
word_document: null
toc: yes
linestretch: 1.3
classoption: fleqn
header-includes:
- \setlength{\mathindent}{0pt}
- \setlength\parindent{0pt}
- \usepackage{amssymb}
---
```{r global_options, include=FALSE, echo = FALSE}
#this sets global knit options (i.e. options for the entire document. The following supresses any warnings from being include in the output and sets plot parameters. Note that setting dev to pdf allows us to set size of graphs easily
rm(list = ls())
knitr::opts_chunk$set(fig.width=12, fig.height=8, fig.path='Figs/',
echo=FALSE, warning=FALSE, message=FALSE, dev = 'pdf')
```
``` {r table p 446}
abC <- 0.3600344
bC <- 0.2455304
intC <- 0.4787285
dfTrans <- data.frame("Prototype" = c("$\\textit{Left/not Blue}$", "Left/Blue", "Right/not Blue", "Right/Blue"),
"$LEFT$" = c(0,1,0,1),
"$\\textit{BLUE}$" = c(0,0,1,1),
`Combined Parameter Estimates` = c(paste("0 x ", round(abC,4), "+ 0 x", round(bC,4), "+ 0 x", round(intC, 4), sep = " "), 8, 9, 0))
library(pander)
panderOptions('table.split.table', 300) # this forces the table to the width of the page.
pander(dfTrans, justify = "left")
```
I'm not sure how to do this with pander, but here is a method using the kable function from knitr and kableExtra functions for detailed table formatting. I haven't changed the yaml markup, but the updated code chunks are pasted in below, followed by the output.
```{r global_options, include=FALSE, echo = FALSE}
#this sets global knit options (i.e. options for the entire document. The following supresses any warnings from being include in the output and sets plot parameters. Note that setting dev to pdf allows us to set size of graphs easily
knitr::opts_chunk$set(fig.width=12, fig.height=8, fig.path='Figs/',
echo=FALSE, warning=FALSE, message=FALSE, dev = 'pdf')
# rm(list = ls()) This is unnecessary. knitr runs the rmarkdown document in a clean session.
library(knitr)
library(kableExtra)
options(knitr.table.format = "latex") # latex output (instead of default html)
library(tidyverse) # For dplyr pipe (%>%) and mutate
```
```{r table p 446}
abC <- 0.3600344
bC <- 0.2455304
intC <- 0.4787285
# I've removed the latex formatting from the data frame code
dfTrans <- data.frame(Prototype = c("Italic_Left/not Blue", "Left/Blue", "Right/not Blue", "Right/Blue"),
LEFT = c(0,1,0,1),
BLUE = c(0,0,1,1),
`Combined Parameter Estimates` = c(paste("0 x ", round(abC,4), "+ 0 x", round(bC,4), "+ 0 x", round(intC, 4), sep = " "), 8, 9, 0))
# Remove periods in column names
names(dfTrans) = gsub("\\.", " ", names(dfTrans))
# Two other options:
# 1. Use the data_frame function from tidyverse, rather than the base data.frame function.
# data_frame doesn't add periods, so you won't need to fix the column names afterwards.
# 2. Set check.names=FALSE in data.frame
# Use kableExtra cell_spec function to format on a cell-by-cell basis
dfTrans = dfTrans %>%
mutate(Prototype = cell_spec(Prototype, color=c("black","blue"),
align=rep(c("l","r"), each=2)))
# Format each of the column names using kableExtra text_spec
names(dfTrans)[1] = text_spec(names(dfTrans)[1], italic=TRUE)
names(dfTrans)[2] = text_spec(names(dfTrans)[2], align="l")
names(dfTrans)[3] = text_spec(names(dfTrans)[3], align="r", italic=TRUE, color="blue")
names(dfTrans)[4] = text_spec(names(dfTrans)[4], align="r")
# Output the table
kable(dfTrans, booktabs=TRUE, escape=FALSE)
```
One thing I'm not sure how to do yet is to format just the first value of dfTrans$Prototype as italic. cell_spec seems to use only the first value of an italic logical vector, so the following italicizes the whole column:
dfTrans = dfTrans %>%
mutate(Prototype = cell_spec(Prototype, color=c("black","blue"),
align=rep(c("l","r"), each=2),
italic=c(TRUE, rep(FALSE, n()-1))))
Here is a huxtable-based solution (my package):
abC <- 0.3600344
bC <- 0.2455304
intC <- 0.4787285
dfTrans <- data.frame(Prototype = c("Italic_Left/not Blue", "Left/Blue", "Right/not Blue", "Right/Blue"),
LEFT = c(0,1,0,1),
BLUE = c(0,0,1,1),
`Combined Parameter Estimates` = c(paste("0 x ", round(abC,4), "+ 0 x", round(bC,4), "+ 0 x", round(intC, 4), sep = " "), 8, 9, 0))
library(huxtable)
huxTrans <- hux(dfTrans, add_colnames = TRUE) # column names become first row
huxTrans[1, 4] <- 'Combined Parameter Estimates' # get rid of the dots
align(huxTrans)[4:5, 1] <- 'right'
text_color(huxTrans)[c(3, 5), 1] <- 'blue'
text_color(huxTrans)[1, 3] <- 'blue'
italic(huxTrans)[1, c(1, 3)] <- TRUE
huxTrans # will automatically become LaTeX in RMarkdown
quick_pdf(huxTrans)
Which looks like this in the terminal:
And this in PDF output:
You can add borders as well if you want.
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.
I have this example below where I create a basic data frame then output it to PDF through LaTeX using knitr. I am controlling some of the basic formatting and have used the function bold to bold the column headers and have redefined my column names through colnames().
However, there is a function called spaces which on it's own will effectively remove spaces from the column headers. Is there a way to combine bold and spaces and pass it into sanitize.colnames.function to avoid renaming the column headers manually?
The intent is to basically manipulate the data frame in R to make it as dynamic as possible when data frames (printed to tables) change during analysis.
Thanks
\documentclass{article}
\begin{document}
%\SweaveOpts{concordance=TRUE}
hello here is a table - Table \ref{tab:mydataframe}
<<testtable, cache=FALSE, eval=TRUE, echo=FALSE, results = 'asis', warning=FALSE, error=FALSE, message=FALSE>>=
library(xtable)
library(printr)
library(knitr)
library(dplyr)
df_one = data.frame(column_one = c(1:10), column_two = c(11:20))
bold = function(x) {paste('{\\textbf{',x,'}}', sep ='')}
spaces = function(x){gsub("\\."," ",x)} # THIS IS NOT USED
colnames(df_one) = c('Column one', 'Column two')
print(xtable(df_one, type = 'latex', caption ='My test dataframe', label ='tab:mydataframe', align='lll', digits = 5), caption.placement ='top', include.rownames = FALSE, table.placement = '!h', sanitize.colnames.function = bold)
#
\end{document}