I am creating a pandoc.table with long column name that I want to wrap so my table does not go off the pdf page. I know you can use split.tables, but that takes away the clarity of the table. Using split.cells doesn't seem to do anything, even when supplied as a vector.
---
output : pdf_document
---
```{r,echo=FALSE, results="asis"}
library(pander)
mytab = data.frame(ReallySuperExtraLongColumnNameThatIWantToWrap=1:2, col2=2001:2002)
pandoc.table(mytab)
```
The following will produce a table with a line break in the header:
```{r,echo=FALSE, results="asis"}
library(pander)
mytab = data.frame("ReallySuperExtraLongColumn\nNameThatIWantToWrap"=1:2,
col2=2001:2002,
check.names = FALSE)
pandoc.table(mytab)
```
The line break is encoded with \n. This is not an allowed character in a columnname, and the data.frame() function would normally remove it. You can use check.names = FALSE to suppress this behaviour and keep the column names exactly as you entered them. Alternatively, you could redefine the column name on a separate line:
mytab = data.frame(ReallySuperExtraLongColumnNameThatIWantToWrap=1:2, col2=2001:2002)
names(mytab)[1] = "ReallySuperExtraLongColumn\nNameThatIWantToWrap"
You can also set the width of the cells with split.cells. The line breaks will then be generated automatically, however, breaks only appear when there is a space in your column header. An example:
```{r,echo=FALSE, results="asis"}
library(pander)
mytab = data.frame("Really Super Extra Long Column Name That I Want To Wrap"=1:2,
col2=2001:2002,
check.names = FALSE)
pandoc.table(mytab, split.cells = 15)
```
This gives breaks after "Extra" and "Name". Note that you still need check.names = FALSE, because also spaces are not allowed in data frame names.
Related
I have the following code in a R Markdown document
```{r echo=FALSE}
s <- summary(indf)
knitr::kable(na.omit(s[,c(1,2)]))
```
The result is:
How can I remove the extra empty column at the beginning?
I am compiling to ioslides
By default, kable adds row names. Trying setting row.names to FALSE:
knitr::kable(na.omit(s[,c(1,2)]), row.names = FALSE)
Try removing the rownames from the data frame.
s <- summary(indf)
rownames(s) <- NULL
knitr::kable(na.omit(s[,c(1,2)]))
My data frame has ugly column names, but when displaying the table in my report, I want to their "real" names including special characters '(', new lines, greek letters, repeated names, etc.
Is there an easy way of replacing the names in knitr to allow such formatting?
Proposed solution
What I have tried to do is suppress the printing of the data frame names and use add_header_above for better names and names that span several columns. Some advice I've seen says to use:
x <- kable(df)
gsub("<thead>.*</thead>", "", x)
to remove the column names. That's fine, but the issue is that when I subsequently add_header_above, the original column names come back. If I use col.names=rep('',times=ncol(d.df)) in kable(...) the names are gone but the row remains, leaving a gap between my new column names and the table body. Here's a code chunk to illustrate:
```{r functions,echo=T}
drawTable <- function(d.df,caption='Given',hdr.above){
require(knitr)
require(kableExtra)
require(dplyr)
hdr.2 <- rep(c('Value','Rank'),times=ncol(d.df)/2)
x <- knitr::kable(d.df,format='latex',align='c',
col.names=rep('',times=ncol(d.df))) %>%
kable_styling(bootstrap_options=c('striped','hover',
'condensed','responsive'),position='center',
font_size = 9,full_width=F)
x %>% add_header_above(hdr.2) %>%
add_header_above(hdr.above)
}
```
```{r}
df <- data.frame(A=c(1,2),B=c(4,2),C=c(3,4),D=c(8,7))
hdr.above <- c('A2','B2','C2','D2')
drawTable(df,hdr.above = hdr.above)
```
I am not sure where you got the advice to replace rownames, but it seems excessively complex. It is much easier just to use the built-in col.names argument within kable. This solution works for both HTML and LaTeX outputs:
---
output:
pdf_document: default
html_document: default
---
```{r functions,echo=T}
require(knitr)
df <- data.frame(A=c(1,2),B=c(4,2),C=c(3,4),D=c(8,7))
knitr::kable(df,
col.names = c("Space in name",
"(Special Characters)",
"$\\delta{m}_1$",
"Space in name"))
```
PDF output:
HTML output:
If you're targeting HTML, then Δ is an option too.
I couldn't get the accepted answer to work on HTML, so used the above.
I'm making weighted tables of row proportions using the questionr package. I want to wrap the column names when they are too long. Because I'm making hundreds of tables, the solution needs to work on tables with varying numbers of columns. I also want to avoid setting all columns to a specific width. Ideally, short column names would remain at their normal width while names exceeding the specified maximum length would be wrapped.
Here are a bunch of solutions I've tried so far, written as .Rmd file:
---
title: "Example"
output: pdf_document
---
```{r setup, include=FALSE}
library(questionr)
library(knitr)
data("happy")
```
A simple weighted table with the "kable" method:
```{r table1, echo=TRUE}
kable(wtd.table(happy$degree, happy$happy, weights = happy$wtssall),
digits = 0)
```
The same "kable" table, but with row proportions:
```{r table2, echo=TRUE}
kable(rprop(wtd.table(happy$degree, happy$happy, weights = happy$wtssall)),
digits = 0)
```
I want to wrap the column headers, but kableExtra::column_spec() gives an error.
Even if it worked it requires manually setting each column width.:
```{r table3, echo=TRUE}
library(kableExtra)
kable(rprop(wtd.table(happy$degree, happy$happy, weights = happy$wtssall)),
digits = 0) %>%
column_spec(column = 2, width = ".25in")
```
Maybe str_wrap will do the trick?
```{r table4, echo=TRUE}
library(stringr)
kable(rprop(wtd.table(happy$degree, str_wrap(happy$happy, width = 8),
weights = happy$wtssall)),
digits = 0)
```
Giving up on knitr::kable(), maybe pander has a solution.
Here is the simple weighted frequency table.
```{r table5, echo=TRUE, results='asis'}
library(pander)
pandoc.table(wtd.table(happy$degree, str_wrap(happy$happy, width = 8),
weights = happy$wtssall),
split.cells=8)
```
So far, so good. But it doesn't work for the table of row proportions,
because the rprop table is of class ([1]"proptab" [2]"table")
while the wtd.table() is just class "table"
```{r table6, echo=TRUE, results='asis', error=TRUE}
pandoc.table(rprop(wtd.table(happy$degree, str_wrap(happy$happy, width = 8),
weights = happy$wtssall)),
split.cells=8)
```
But wait! I can pass a kable() product as pandoc output.
This table looks great, but I don't think I pass any
pandoc.table() arguments like "split.cells=8" to it.
```{r table7, echo=TRUE, results='asis', error=TRUE}
kable(rprop(wtd.table(happy$degree, happy$happy, weights = happy$wtssall)),
digits = 0, format = "pandoc")
```
And here is what the output of that .Rmd file looks like:
At least, for kableExtra, you need to specify format in your kable function to be either latex or html.
To make it dynamic, you can save the table to a variable before it goes into kable and use 2:(ncol(your_table) + 1) in the column_spec function (+1 for the column_name column).
I am trying to combine two tables in R Markdown into a single table, one below the other & retaining the header. The figure below shows the desired output. After putting my markdown code I will show the actual output. I realize that the way I have structured the pander statements will not allow me to get the output I want but searching SO I was unsuccessful in finding the right way to do so.
I can do some post processing in Word to get the output exactly as I want but I am trying to avoid that overhead.
The testdat.RData file is here: https://drive.google.com/file/d/0B0hTmthiX5dpWDd5UTdlbWhocVE/view?usp=sharing
The R Markdown RMD file is here: https://drive.google.com/file/d/0B0hTmthiX5dpSEFIcGRNQ1MzM1E/view?usp=sharing
Desired Output
```{r,echo=FALSE,message = FALSE, tidy=TRUE}
library(pander)
load("testdat.RData")
pander::pander(t1,big.mark=',', justify=c('left','right','right','right'))
pander::pander(t2,big.mark=',', justify=c('left','right','right','right'))
```
Actual Output
Thanks,
Krishnan
Here's my attempt using the xtable package:
```{r,echo=FALSE, message = FALSE, results="asis"}
library(xtable)
# Add thousands separator
t1[-1] = sapply(t1[-1], formatC, big.mark=",")
t2[-1] = sapply(t2[-1], formatC, big.mark=",")
t1$Mode = as.character(t1$Mode)
# Bind together t1, extra row of column names, and t2
t1t2 = rbind(t1, names(t1), t2)
# Render the table using xtable
print(xtable(t1t2, align="rrrrr"), # Right-align all columns (includes extra value for row names)
include.rownames=FALSE, # Don't print rownames
hline.after=NULL,
# Add midrules before/after each set column names
add.to.row = list(pos = list(-1,0,4,5),
command = rep("\\midrule \n",4)))
```
And here's the output:
Allow me to make a formal answer since my comment seemed to work for you.
pander(rbind(t1,names(t2),t2))
This question already has answers here:
Simple example of using tables + knitr for latex
(2 answers)
Closed 7 years ago.
I ended up using tables package with knitr, but I can not figure out how to get a multiline header. Here is the code:
<<test_table, results='asis', echo=FALSE>>=
matrix <- matrix(1:9, nrow = 3)
colnames(matrix) <- c("first column", "seconf column which I want to have 2 lines because of its very long header title", "third column")
library(tables)
table <- as.tabular(matrix)
latex(table)
#
It's probably possible to do this with the tables package, but xtable provides a very easy solution. The following minimal example shows two different approaches:
\documentclass{article}
\begin{document}
<<setup, echo = FALSE>>=
library(xtable)
library(knitr)
opts_chunk$set(echo = FALSE, results = "asis")
matrix <- matrix(1:9, nrow = 3)
colnames(matrix) <- c(
"first column",
"second column which I want to have 2 lines because of its very long header title",
"third column")
#
<<ChangeColumnType>>=
print(xtable(matrix, align = c("r", "r", "p{4cm}", "r")), include.rownames = FALSE)
#
<<ChangeOnlyCell>>=
colnames(matrix)[2] <- "\\multicolumn{1}{p{4cm}}{second column which I want to have 2 lines because of its very long header title}"
print(xtable(matrix), include.rownames = FALSE, sanitize.colnames.function = identity)
#
\end{document}
The first approach (chunk ChangeColumnType) is very simple: It sets the column type of column 2 to p{4cm}. That gives a column that is 4cm wide with automatic text wrapping (see wikibooks.org for more details). The drawback is, that this affects the whole column, not only the cell in the first row.
The second approach (chunk ChangeOnlyCell) uses default alignment (or whatever you want to specify via align) and changes only the column type of the problematic cell using \multcolumn.
By default, xtable "sanitizes" your table, meaning that all special latex characters will be escaped. This is handy because you cannot (easily) break your TEX code, but here we manually want to inject LaTeX code, so we have to turn this off. Therefore, set sanitize.colnames.function = identiy. All column names will be used as you specify them – so be careful when using characters with a special meaning in LaTeX.
The example from above delivers the following tables: